forked from I2P_Developers/i2p.i2p
Compare commits
2501 Commits
i2p-0.9.7
...
i2p-0.9.24
Author | SHA1 | Date | |
---|---|---|---|
bccefb949f | |||
ddf056cf1d | |||
ddb9777638 | |||
374996d8b2 | |||
6192aa6910 | |||
8e47ec325d | |||
e7081491ca | |||
594abdee55 | |||
d08f29d7d6 | |||
4342aa6bce | |||
ec27458393 | |||
f0dc76983a | |||
71c4505617 | |||
acfb0a1e3b | |||
ff66d9db67 | |||
6edd2b97b9 | |||
cdfd4ca2f4 | |||
308c9da384 | |||
ca00ea7a76 | |||
e2b7f504b0 | |||
20547238fc | |||
9caddc166b | |||
c546b283fd | |||
c8197b8181 | |||
35739289cd | |||
68d8c6e556 | |||
f85d03085b | |||
6917203530 | |||
144f54eb8c | |||
46af643ca8 | |||
2698076fb6 | |||
2f09389ddd | |||
8da3257856 | |||
a4546e1045 | |||
3bce2f5d46 | |||
074c5aa16c | |||
879b70617b | |||
cad0ab17dc | |||
4250f78ddf | |||
cc4bf8ea16 | |||
05b40a220d | |||
64f5c662fa | |||
e9146ebc77 | |||
d5990cc0f2 | |||
b6bd497e52 | |||
2246e21340 | |||
c60f3970d1 | |||
0b94d866f0 | |||
fa6643c5a2 | |||
d0eaf4d899 | |||
c59496f30f | |||
8226e92973 | |||
af26f73f99 | |||
95946606ef | |||
3c5f9d0bc3 | |||
2155347e4f | |||
db86850d15 | |||
97ae1e5034 | |||
fee755bdb7 | |||
4fe24790fd | |||
68ecd82755 | |||
2c1b9c2d37 | |||
cddc1b362e | |||
89bdbedc0f | |||
3a4e82f025 | |||
c8aca62d03 | |||
8b9bcbc777 | |||
00d6a49653 | |||
ea9c4a1957 | |||
7680ecbdc4 | |||
00a5d19534 | |||
2d1ac7b266 | |||
2852383e4e | |||
393b593785 | |||
32df925fa6 | |||
9b2bbe03ee | |||
7e872088d0 | |||
77a6db1cab | |||
bb56a11bda | |||
7ea2be387e | |||
81cb62fda7 | |||
8b42896cc6 | |||
9ba5ad7bb1 | |||
f7ede4bf6f | |||
64f2318720 | |||
34202e6c4e | |||
af8b8ecddd | |||
0558bc41a3 | |||
d45dc8d0f3 | |||
b6e8431bce | |||
826bb54984 | |||
fdc160cf1d | |||
5a7fc3f7f4 | |||
a35ecda992 | |||
89e60fa8c5 | |||
6e2e4ca6d8 | |||
eaae06028e | |||
997ef73d50 | |||
ff4d575196 | |||
68c312139e | |||
cab69f6583 | |||
5bd0041f8b | |||
53ae4125e5 | |||
b53fe37a30 | |||
348805f012 | |||
72527f4d33 | |||
dfbbe3e928 | |||
f778c23f0b | |||
3c8cc16273 | |||
1c1511267d | |||
55f729986b | |||
23df322056 | |||
d5717ca12d | |||
74fac4b1d8 | |||
a5a702744f | |||
1db7613519 | |||
68b4ad2238 | |||
513e1b9ff8 | |||
dffd441304 | |||
87fa1cb1ac | |||
38c8e017a8 | |||
7b83e23269 | |||
415b51bc49 | |||
a03339b120 | |||
b1668bbc11 | |||
9ce8fced02 | |||
01d23713af | |||
2849aec3c2 | |||
cb979fb685 | |||
bafec18093 | |||
5adbf9050a | |||
3a25a91c33 | |||
0519ea476e | |||
48d7f4969c | |||
ed1567e9f7 | |||
9f625a03fb | |||
e77c5bd05c | |||
31ace20256 | |||
4291450f37 | |||
6373c8a9ed | |||
bd048b04cc | |||
b9ab933550 | |||
626f5415c7 | |||
9367aca50a | |||
e5f186f61a | |||
807e5bf966 | |||
8d7edaae61 | |||
868e5e988c | |||
612e01cbbf | |||
13fd613bb8 | |||
6b67a70bbd | |||
6934599eed | |||
730dea377a | |||
5d07294cc6 | |||
6081856dd1 | |||
92bb2dbda7 | |||
5c4189abdf | |||
2400a77e25 | |||
110a0a1b7a | |||
302ec7767a | |||
1215a70aab | |||
ce96234fdb | |||
9a9832cb77 | |||
d30c1ec319 | |||
7649132259 | |||
9efb3c8751 | |||
07c9ddb38f | |||
be498eaab8 | |||
9e8597aa05 | |||
5b4a4f6c84 | |||
a468b3e8b4 | |||
c7d68c2a6c | |||
16549aa49a | |||
b59a8027bb | |||
8d9d3fcf95 | |||
1a7bf2a0c3 | |||
bb8e6127d3 | |||
13987b7d50 | |||
dfb8830802 | |||
9483e095d9 | |||
46f42432a2 | |||
599989deba | |||
1e89fac192 | |||
4c72c08d65 | |||
679fe9b044 | |||
6fb0692d57 | |||
38a1a96db2 | |||
bbaa6f7f87 | |||
046ef07efd | |||
fc7939b404 | |||
dd6a3f14ec | |||
99c9b30e49 | |||
f5ae9c23fe | |||
23cb4ca764 | |||
231040ddd8 | |||
7a75e2e662 | |||
e6644236ed | |||
8a1f02aa89 | |||
ded249dd3d | |||
a028bba997 | |||
c609781927 | |||
51c5da3f72 | |||
37a4fcb469 | |||
e93e76a362 | |||
c1afbd37d7 | |||
3fa2fb4c8d | |||
ffddf415c0 | |||
03a99adaab | |||
48f294024c | |||
123b4ca460 | |||
c944fcce96 | |||
1451dc6ece | |||
1aed266f70 | |||
e120a8a3a3 | |||
a3e16614ae | |||
bdde11c0ef | |||
63ddf11799 | |||
a3b55ccdea | |||
8e77188560 | |||
1e5a35c7f8 | |||
83b923151c | |||
e4ebb9a77d | |||
077c4a073f | |||
f5bf4ec8ea | |||
c901010d96 | |||
9f0f1f5ec8 | |||
7175b1cdb9 | |||
ca4642e0f0 | |||
6bb156a436 | |||
19090343ba | |||
b15138dd67 | |||
5f50f23fe1 | |||
d5e2defb5f | |||
c1d77dfe5c | |||
eca234c187 | |||
1a6074a62b | |||
9baeedbc27 | |||
3f91e448c0 | |||
3e25ff251b | |||
f8830a759e | |||
b15ea8ba2f | |||
ef428d559e | |||
39d749ba16 | |||
a3a092a454 | |||
787921aa89 | |||
bbb6da2ac6 | |||
b7dc55e326 | |||
805979b987 | |||
c37cc7ad52 | |||
02c1417cc5 | |||
627d0d29db | |||
c595895877 | |||
6efce31eed | |||
f713a19785 | |||
abc0f4c720 | |||
71bc55b470 | |||
5f175455c7 | |||
9bddba56a0 | |||
4e6ddfcea3 | |||
3411a7c884 | |||
70921a2b09 | |||
dd36176997 | |||
fe26052189 | |||
ba1488bcce | |||
39b218b216 | |||
b43417bf77 | |||
649a63db6f | |||
6aa8ed1280 | |||
9224afb78d | |||
5e879b85a8 | |||
2c03b434e1 | |||
55a6f44651 | |||
971a2652e3 | |||
68aa8800b6 | |||
dd4d12f287 | |||
7063609f05 | |||
b32c8d5fa4 | |||
843e2a8a0e | |||
419d6a8e18 | |||
03f9df4ff0 | |||
f4a6cf2002 | |||
f93da93cf0 | |||
b068f9a262 | |||
5fa059b4a8 | |||
2f92b27446 | |||
5d345f65a3 | |||
ccc8c04782 | |||
58ccfed41d | |||
59b05d4214 | |||
f46a902256 | |||
39b810bd79 | |||
22417715e7 | |||
d21777fbc1 | |||
b22a6bc163 | |||
1c3527e1a4 | |||
4d7ad6ef7f | |||
3ea8b477d8 | |||
ea4dd12bff | |||
a13552dd8d | |||
89c14c2e9a | |||
22b9876b68 | |||
04690bed9f | |||
0faa5ba2f4 | |||
04d653a8b9 | |||
3f213cf1db | |||
53ae727935 | |||
62acfc0cae | |||
5a2f22b00f | |||
7dd438b5f0 | |||
6685b81834 | |||
c56f686d8c | |||
b81cbedd5c | |||
02a0ef3526 | |||
cfc0664756 | |||
2a3b55f3a4 | |||
287f94ad19 | |||
462c882f4e | |||
b8a909c4cc | |||
83791b2d10 | |||
ff420278c5 | |||
1a385b6dca | |||
64889b2bc2 | |||
bfc6534b20 | |||
84abfa0190 | |||
d5a0d95c61 | |||
1de840ce59 | |||
0f6176b7bf | |||
3d533a406d | |||
37597b8c7d | |||
addc9c5ca3 | |||
a2e38503fe | |||
7912d7650d | |||
6f5739b9d8 | |||
ed3e444d1e | |||
ac1a28e988 | |||
7117438b04 | |||
d5cbccf186 | |||
fd606064d9 | |||
9d05424202 | |||
157d494dee | |||
fa792a9d5e | |||
ab134261f0 | |||
de2431e9ee | |||
c4cbd7d5c4 | |||
e978bb81a0 | |||
2c6edf401f | |||
fe69d3b8f7 | |||
61edd01e3d | |||
483d7c43ee | |||
7c703953be | |||
f577a94012 | |||
b10b8581cc | |||
601376561b | |||
5a11a28a35 | |||
fde0ae8349 | |||
b5944045fb | |||
ecd0231cd0 | |||
44b35f328b | |||
f3bb20d750 | |||
20cb284f9d | |||
b4993d42b3 | |||
9b466f3261 | |||
0bf9cb3bf2 | |||
9efe60d7a8 | |||
45fe238227 | |||
e704baddd8 | |||
db9555dba3 | |||
4b34b49dc1 | |||
1652bb39e3 | |||
5eda1e0031 | |||
b19866cbc4 | |||
48bcc031da | |||
f1998e6377 | |||
6f1bb85397 | |||
d848a19ab0 | |||
8dcbc9958e | |||
63555acd21 | |||
c451014eea | |||
9fad9347c1 | |||
841e27f35c | |||
bfde521cf9 | |||
fea6b8aec3 | |||
8d3fb0c9a1 | |||
d662514f74 | |||
44bd14bd4d | |||
1681598dec | |||
809a533573 | |||
265e4b58a5 | |||
93854e93b5 | |||
f6605d05d9 | |||
c20772702a | |||
ba5af15c6f | |||
9af197e590 | |||
2f59a4b3e6 | |||
8b14afd605 | |||
63e934f8f2 | |||
dd5f804150 | |||
35b0e99ff0 | |||
1ed1e4414b | |||
d087fd674b | |||
1f9bb046f5 | |||
914cc120ad | |||
631a0674ab | |||
17d26976d5 | |||
dc9d60e261 | |||
2c191e7bf8 | |||
817888c23c | |||
1eaf376ee7 | |||
6cb3d1d330 | |||
2681c4b42f | |||
05959d5199 | |||
113a8a52f3 | |||
98a4460bde | |||
3645c906e8 | |||
fcdd8be7a7 | |||
34f6f65104 | |||
4c516cd2af | |||
8ea6805f8d | |||
23f2261bd9 | |||
6e06d326e3 | |||
072e4dc2bf | |||
f56ac66d64 | |||
c662f17823 | |||
246b376ed9 | |||
194f20e18c | |||
9b2d416154 | |||
12385f04ec | |||
49e68bcc86 | |||
b82c1ead72 | |||
33672e6a86 | |||
876729c24e | |||
b6cb074c04 | |||
dd47389ad1 | |||
25268e7cb2 | |||
355b2a1528 | |||
975149d049 | |||
af394e13ad | |||
e3f64f6edf | |||
2fbbfa388e | |||
0b4d4ddcbc | |||
428d89a307 | |||
feff6c003b | |||
699d550992 | |||
c6896c4418 | |||
1b2d4c75eb | |||
586defc802 | |||
2499aad51d | |||
addb142ecd | |||
20c796e87a | |||
cd62d7170c | |||
acc647822f | |||
1cf544f1d4 | |||
0f4e09500c | |||
7c5dfaee20 | |||
8d9cced128 | |||
8096e4f65d | |||
5878fae88f | |||
036b77746b | |||
233cce8311 | |||
bc85543ef2 | |||
627f7076b0 | |||
863e120204 | |||
53cfba4cbd | |||
3a774b7c37 | |||
0ad34a4b00 | |||
2b9ffc1270 | |||
93c7860d2b | |||
25f6c3d9e1 | |||
b9e07bc9aa | |||
09f68e44ca | |||
013b5fd85b | |||
8962bfb6bc | |||
605602e001 | |||
f341e5566b | |||
7b84676f4a | |||
c666f8a4f9 | |||
e067761947 | |||
226bee64ef | |||
1a40e57413 | |||
f73101b014 | |||
fef65c996f | |||
cbc2f899a6 | |||
099515adff | |||
ff2ea9ac3e | |||
97aeecd865 | |||
8098d705f9 | |||
fa8c390267 | |||
e8f4e19bac | |||
9041a2c69f | |||
384e9118c6 | |||
0936a2ee23 | |||
bc6b0c12ac | |||
f6f051cfa4 | |||
fb131a040c | |||
9f2ded6073 | |||
55e36ee458 | |||
7c13fb2ba0 | |||
663ccb72d7 | |||
78e0a37fc9 | |||
09cdc00939 | |||
2590e7d4ff | |||
27f56776ca | |||
657f13af29 | |||
e2ca74963f | |||
9304cb2bbc | |||
362086994a | |||
f57e37d588 | |||
d96ddd1a0e | |||
7b711ebba0 | |||
0762715264 | |||
8a69dc0a97 | |||
39dc60cf8a | |||
09e867b194 | |||
dc9256f274 | |||
272f63dbbd | |||
06104118d0 | |||
525ec01c1e | |||
f8594c316f | |||
3c89bd4e19 | |||
1f8408f417 | |||
915b35f0c1 | |||
4521156ecb | |||
c58fd8f84e | |||
f02b401b7a | |||
4fdcb6ce29 | |||
94824e4d2b | |||
280fc05c91 | |||
89745f5002 | |||
7715e6484c | |||
c807194e93 | |||
3602f73497 | |||
4bf115b5f6 | |||
7ab85a0a20 | |||
fba0372339 | |||
03dfa6515b | |||
5e33ed1169 | |||
11ab7fc56c | |||
716bff41d7 | |||
1d8842cfc8 | |||
042b03d6b8 | |||
ab753651b9 | |||
4ea99b8a10 | |||
3d07e1a10b | |||
86525e7239 | |||
195171f9ed | |||
33c4be5b2f | |||
fea2c3c6b2 | |||
281686ba58 | |||
0b91fcb636 | |||
807f1381fb | |||
ac56a63809 | |||
e4798b9ed8 | |||
7584346c82 | |||
29330aa5d3 | |||
65ff2c0afe | |||
de4d47de95 | |||
ae41a3f316 | |||
2dc3d68418 | |||
5eb43b6ae4 | |||
0c672ecc49 | |||
3b6d98fe38 | |||
b3472cfe80 | |||
38f2b93c7a | |||
e7af87a981 | |||
d698a67660 | |||
b38f2d62a8 | |||
10556bca75 | |||
1f17d2a149 | |||
dc777c8de5 | |||
1fb9643916 | |||
081f1865a8 | |||
0e17c560b3 | |||
a3b1327934 | |||
e68ca573f0 | |||
b5455cee6e | |||
cbdc1403bf | |||
40130a8a61 | |||
ca14055976 | |||
8303016b48 | |||
287862887d | |||
f25d2a3d3f | |||
7f30f481b2 | |||
5ee6826241 | |||
68951c4c6b | |||
5dc7497802 | |||
31cfddc218 | |||
c1e70ac7d2 | |||
dd9abd3f09 | |||
2f5e64e532 | |||
b12f988390 | |||
9f3d5bf57b | |||
7f9e958e5a | |||
c4877ea092 | |||
2aafc23774 | |||
77c9a644ac | |||
abd8ca34dc | |||
31435685bf | |||
7337fd0670 | |||
f7b7a98b9d | |||
2226936737 | |||
8b293b2190 | |||
94bba8d11f | |||
5c2b5075f9 | |||
ca6820a4c0 | |||
2fafa3337f | |||
b5f75a4bb9 | |||
707bfbbf8b | |||
1eba6c5167 | |||
a14208b841 | |||
83966f9a7f | |||
d89f06015b | |||
49f786c928 | |||
e8bc0bd5d1 | |||
8d69b69357 | |||
e7b9a230e6 | |||
6385c412fd | |||
bb33b358b4 | |||
572f071cfe | |||
42cb89f525 | |||
1868d2b50f | |||
4588f1ec75 | |||
629f7f05c7 | |||
0f18686243 | |||
2a2587b13d | |||
489fdd5e4b | |||
fe680eb192 | |||
613440ff63 | |||
64121b1e92 | |||
f16927f316 | |||
cb50c1bd8b | |||
921ad86274 | |||
ac76107752 | |||
2359b1edd2 | |||
2750681d78 | |||
eaac4d3de0 | |||
f243968dfa | |||
8d9e2bdc71 | |||
6dbbb6b61b | |||
f89bf32390 | |||
ef195aa4ef | |||
843230a1cb | |||
84e63f3b38 | |||
b90816fdf8 | |||
40c4a42921 | |||
26f89391d3 | |||
aaae72cf84 | |||
3e55cff153 | |||
bd778a2204 | |||
235c196f14 | |||
e475c161cb | |||
08e96109a7 | |||
81ad33d9e3 | |||
aecc95825b | |||
37c6ac3a88 | |||
772d0beac3 | |||
64fdfd81ee | |||
1b09b9faa4 | |||
6f0ebb2d94 | |||
cbe91e3012 | |||
238501919b | |||
ae3a5f7b25 | |||
638cadc3c9 | |||
da0036581c | |||
59a58ea310 | |||
bebe5f8a4e | |||
c3af99685d | |||
e1d9e05b8d | |||
212f6b472a | |||
fdada78edf | |||
638c5429d2 | |||
b67bbd7065 | |||
1caf3e778b | |||
fd82fff07a | |||
a6ac8f8c09 | |||
19a26f8e22 | |||
46e85cf265 | |||
8f321b5427 | |||
e1f8f1a3f4 | |||
935a5b573d | |||
8c2636aa99 | |||
03ddb1075c | |||
72eb2c058c | |||
a100d2ccf9 | |||
ecfb3e94c8 | |||
c31d6b1ac1 | |||
65993e1d50 | |||
47c4c0d6bb | |||
b2872e6110 | |||
b8c8d5b447 | |||
32049d7bfc | |||
f0fdb35ba6 | |||
d8baf62966 | |||
be8f7f9676 | |||
57b641bf63 | |||
ff5d29de1a | |||
91e98ba447 | |||
6a644dd0e5 | |||
7b82393336 | |||
22993e1ea6 | |||
341bd6d7ca | |||
13d5a36cfc | |||
f3bb84f2c0 | |||
1d496404be | |||
51233371e0 | |||
bc0a7ebbbc | |||
72c78b3870 | |||
5555c52376 | |||
e1842be049 | |||
6ceb4fcf42 | |||
50b68d4e1c | |||
3f46228f0b | |||
6c954f0b68 | |||
69c2ed77a0 | |||
6f09224bdc | |||
568c90806d | |||
6e451c8d4d | |||
12fd585625 | |||
997fbb3392 | |||
089626f6b1 | |||
71d2049fe8 | |||
e5aee3001f | |||
ec62bcbf8e | |||
a8f013f3e4 | |||
037cd78dc7 | |||
b31ae4bae5 | |||
54dba980b4 | |||
dc19d2fab3 | |||
3a57310fbe | |||
749e19a1c3 | |||
de6608f6b8 | |||
cd6d9cdd94 | |||
e45413d417 | |||
11c3230150 | |||
dd99978b19 | |||
dd265bbd54 | |||
f5ba1b1b97 | |||
7825f0f84f | |||
69a0324e86 | |||
957d3545b6 | |||
466348a8c5 | |||
e5b7e97ff4 | |||
4613e5f847 | |||
44f8154f07 | |||
5486874d1a | |||
d868ca4740 | |||
780479be4b | |||
4705f01bc5 | |||
2f5f91a084 | |||
e44fe98c7e | |||
d8fbc9c170 | |||
facbe8f9a0 | |||
4d8e577ffd | |||
80eb7635c1 | |||
e3103762b6 | |||
cce710e377 | |||
013c79bc45 | |||
1e375886bd | |||
d1ac24c65d | |||
6aa1284848 | |||
bb082c35fc | |||
f7577e7de8 | |||
b5df13d8b7 | |||
9d76790cc5 | |||
706ee243a5 | |||
351a1a8d27 | |||
6916cd7977 | |||
a444c25c2c | |||
45bc533e38 | |||
03e890b01c | |||
0c90162e20 | |||
ddc3ef8db3 | |||
fcec43b7ca | |||
edb614d970 | |||
820b99e3d3 | |||
cf0453cee0 | |||
75a8d8f6d3 | |||
1ac8d99145 | |||
b7b5512e7a | |||
485acd6c8d | |||
bb68728c82 | |||
f3b2eb69d2 | |||
168d688fc9 | |||
ade93ea76d | |||
44503af88b | |||
eb7693561b | |||
3ccb03f9be | |||
f3a2af8f10 | |||
2ef615a3f7 | |||
20197fc3ec | |||
fadc624f7c | |||
22c4149358 | |||
c770c6bc6a | |||
891408191e | |||
9a8fa246a9 | |||
83c3152b5d | |||
956730c5e9 | |||
72b9c92a6e | |||
349255d252 | |||
ac902badcd | |||
9dc2ae0d7e | |||
188bd6db7b | |||
3a8ce64c84 | |||
f3d573cab0 | |||
9e18c7ea18 | |||
a975dc4427 | |||
b875e284af | |||
46fe4298b9 | |||
9790d3ba64 | |||
2d31f30a22 | |||
2fefe93922 | |||
399b068a4e | |||
dcffde6eeb | |||
78074f6a7e | |||
79dc01f7e4 | |||
0f6040ecb1 | |||
a0ab72e362 | |||
2c45378c6d | |||
44c75187f5 | |||
2609a4d124 | |||
2d58501db3 | |||
a337185820 | |||
9c0aa0c271 | |||
b2e908f094 | |||
ef32d37073 | |||
f0961a9658 | |||
876b5714be | |||
825cd7ff4c | |||
47f3476078 | |||
7b10ebc117 | |||
e5cdfd206d | |||
dd4c62b560 | |||
aae801efaf | |||
e02d44433d | |||
590a3c98e5 | |||
7f472e4ee9 | |||
a3802d4d8b | |||
59348f8dbd | |||
8742a66f2f | |||
a2f027e136 | |||
cb4359cd0a | |||
163c172823 | |||
80a2d2c1f5 | |||
486f282999 | |||
1293dccf35 | |||
91fe62eee3 | |||
d3f5596cb2 | |||
d7a88db87a | |||
0af1f67c33 | |||
8dde7b70db | |||
64faeef6c4 | |||
c79e4aeaea | |||
8b6a86e391 | |||
92daf4a8df | |||
819b07a52a | |||
b8f8c6129d | |||
25d1ae195a | |||
d22b05e114 | |||
db25eff74a | |||
c927441d66 | |||
7e4832d5f2 | |||
819b35c760 | |||
071498c413 | |||
7125ed0492 | |||
de201bdd9c | |||
4fccd258e6 | |||
56d705739b | |||
2a9d61b1ed | |||
a9f6839a04 | |||
5b555855ef | |||
76cf80a3d0 | |||
4c6aaa32b6 | |||
74ab1bff53 | |||
b5bba5e3c8 | |||
7e5bd17714 | |||
ec6207fc78 | |||
36d47a0ba9 | |||
0289cefd8d | |||
521eb2d8f8 | |||
0494266649 | |||
8fac5c064e | |||
0b6f74e646 | |||
b8b272a5b8 | |||
a570e09166 | |||
1919e36c30 | |||
812c00f11e | |||
419e27cfd1 | |||
d761c02909 | |||
c7d1d2b69a | |||
0972b6b56a | |||
6e3cf7869f | |||
f7337b4891 | |||
55161dec17 | |||
b65b53b0df | |||
49e1e1c8a4 | |||
9b73fcda40 | |||
b92e1ee9aa | |||
04ac54cd35 | |||
d47916f753 | |||
b0ea1d691a | |||
ce041dfbc1 | |||
4613da093d | |||
2d5f7aaae5 | |||
5a7a7ac83d | |||
f217af2deb | |||
6d58f9a354 | |||
29953ea5e4 | |||
bb9cef1e40 | |||
ece2f1484c | |||
a3c8a4363d | |||
2f90b5a201 | |||
d4bbdc28f3 | |||
f41df969b7 | |||
f87d006a1c | |||
f4fa9a7d8f | |||
c52047e6cd | |||
9163d41228 | |||
1be9bb29e8 | |||
522a89a045 | |||
06b9b6a7fb | |||
7f9c565cd7 | |||
201afc823e | |||
f4c79c885a | |||
656202c9db | |||
72b64072d5 | |||
b72271f9a4 | |||
b0d09d28f4 | |||
b9197e35b5 | |||
e431be2cbe | |||
761c883c1f | |||
60f86f342b | |||
1234b6b148 | |||
6f45242fc8 | |||
36c45ccb7b | |||
90cf71b5bc | |||
7165dc7860 | |||
5491287931 | |||
7256096b8a | |||
b6008b5414 | |||
1042d21278 | |||
47eff7ee86 | |||
3da850a6b9 | |||
a1358deda2 | |||
df0bbfd615 | |||
0568ac3aa5 | |||
e63a69170e | |||
711f8dedd9 | |||
09c3737a94 | |||
9384424173 | |||
4936f08212 | |||
03f4ebbe35 | |||
0671785ab2 | |||
381dbc4b4a | |||
84cf531f5f | |||
175806115b | |||
86b45ab1e5 | |||
17939036bc | |||
5bf515441e | |||
06edb9f2a6 | |||
33b58f5fab | |||
47a012a4dd | |||
e5801be43e | |||
d5a6ac591c | |||
59373f9bdf | |||
5da492b9e5 | |||
9bcc951f10 | |||
3270ba840e | |||
45b3e44cc2 | |||
7ed855b2d2 | |||
f08552c2d1 | |||
9a4c19b24b | |||
690b695373 | |||
65348b2365 | |||
285c13d900 | |||
0a938d9048 | |||
a02a265802 | |||
eeeeef81cf | |||
bcb9fe5f24 | |||
37f34d83f8 | |||
b3238079c3 | |||
ee1edb3383 | |||
7767430af2 | |||
2e5185aa99 | |||
6e847a4cc4 | |||
045f6dccf8 | |||
d7895a456a | |||
7753d05b61 | |||
043b4776c3 | |||
5db764de5f | |||
3ae846a713 | |||
927e29b8ef | |||
d271411552 | |||
31d98ac4a5 | |||
78f4cc8e30 | |||
cce30a8f42 | |||
a9e928fb46 | |||
60017f7c55 | |||
eb46f74e24 | |||
5e890bd781 | |||
20facf78d0 | |||
96db43cc8e | |||
ab4f209c10 | |||
fa51a0aef4 | |||
aa6a5e053c | |||
03df6c2ba0 | |||
501f645e60 | |||
23534b31c6 | |||
d35363cdbc | |||
ba34c90b7f | |||
94a19171ed | |||
8099591589 | |||
df6bbc59b3 | |||
05a616aa0d | |||
c84105e783 | |||
262721cc90 | |||
c24168d5cd | |||
4e529a68d3 | |||
4f3244e93b | |||
b2e17916e4 | |||
57ac344e7f | |||
98e275d908 | |||
8420b6c715 | |||
3dfcb2d5cc | |||
540720a912 | |||
f86200e3ae | |||
9e43618028 | |||
aacdba1bc7 | |||
c28d060d52 | |||
bf3fdbb1ab | |||
0a7a637d46 | |||
e842165265 | |||
2db82da910 | |||
9953bc3024 | |||
2ba4992d88 | |||
5e67008d26 | |||
e7b50c5940 | |||
78d7277298 | |||
fb641187b8 | |||
4b2715c36f | |||
f1e9f5d4fd | |||
2d43d349ab | |||
7ab6708a3c | |||
7010d9b524 | |||
947a3a2181 | |||
0ff87ef8cb | |||
ec20150ffd | |||
30876a9cd3 | |||
1773fc0e0d | |||
6d6f7fb89b | |||
449ce3176e | |||
be8832e87f | |||
5999690665 | |||
285fa6cbc9 | |||
9700f30c35 | |||
a38bd0b5cf | |||
5383f9f097 | |||
a16d17c422 | |||
5f2b620819 | |||
fd47cb88de | |||
77e7982e74 | |||
04cd1cedda | |||
3ef89f49e7 | |||
2a681608b5 | |||
a52c06a6c6 | |||
49b8a65ad9 | |||
9781cb72ac | |||
f7e83fb839 | |||
ce2a2cf684 | |||
c88fa70f82 | |||
f76744a0c0 | |||
31cc0764a9 | |||
15137d9b62 | |||
8f8adfa39e | |||
5044f3e58f | |||
279e102d7a | |||
7f72830ec8 | |||
2caaad95ec | |||
09b995aca6 | |||
a0bf8433e4 | |||
9104bd7304 | |||
2f2aa7f5a8 | |||
0773a30578 | |||
962f5efe6b | |||
6dc3cd9650 | |||
397ae536f9 | |||
f19ec4bd44 | |||
fd7e549915 | |||
7a7ae77c83 | |||
1a9fb381ed | |||
ae7bfceafb | |||
a961843aa6 | |||
43c6a4ddac | |||
ae1d5648d5 | |||
2d3e8e0c4e | |||
4691fc69d5 | |||
cb87f9f307 | |||
5f1e5bc271 | |||
1c6d5ad2db | |||
555189f123 | |||
049044b827 | |||
cfd9e2c3ab | |||
a0b457b9a1 | |||
23f24c7d39 | |||
6112cc5a38 | |||
7deb8c1bcb | |||
76e4b49d9d | |||
5ae267a8a2 | |||
f524351041 | |||
893d1bb45f | |||
945988dfb7 | |||
62698664a2 | |||
0d2892c75d | |||
ecc72e6825 | |||
531d520ceb | |||
4e72e150ad | |||
b28628b8e1 | |||
702830ad0e | |||
6ca0c54ba7 | |||
634bf5f7e3 | |||
2284c963af | |||
ad2052395f | |||
e9a1dbf8f1 | |||
703b21e89b | |||
36ea2cca6b | |||
8b2cf770a5 | |||
7d6d801943 | |||
d705b43f3a | |||
a18ed194cb | |||
a3e4293fd8 | |||
df144d8434 | |||
bab1e05235 | |||
a1fdd41b0e | |||
60d9c1651a | |||
ec1380dfa1 | |||
798275608e | |||
0f2affd414 | |||
7695b51d89 | |||
fb99122d83 | |||
6d53838e20 | |||
ec3fd9a7d7 | |||
304f2ebb7b | |||
4976e84488 | |||
2ebacb1b9b | |||
d085f9ea66 | |||
e275117569 | |||
eae277fb77 | |||
d7130c15cc | |||
937a17c5dd | |||
b6234e1d5e | |||
7955b8ae71 | |||
a36ef62358 | |||
bcbda3cd27 | |||
239fe518a9 | |||
44d6e117d5 | |||
8a12b7cb41 | |||
4d4308c486 | |||
abcdcf2e8c | |||
44b753d1e5 | |||
83b3f242a9 | |||
86c43f4734 | |||
be0cb84f97 | |||
3bea7f5ad5 | |||
266a20d55e | |||
d2c6a80d24 | |||
cd51fbc2a6 | |||
73256f6030 | |||
e081f94d9f | |||
e96cc09d75 | |||
d87178fec3 | |||
28ad95f892 | |||
8270a92a44 | |||
088290c544 | |||
6685acfef4 | |||
1d1a05ee7b | |||
bbeb429a59 | |||
55af588c2c | |||
80d0313fe5 | |||
853d309960 | |||
564400597a | |||
1c2b6fc00e | |||
7b6f32e5b2 | |||
dd4acc88a1 | |||
6e566f6e3d | |||
fff7fbe121 | |||
a50afeb5d5 | |||
49eeb99d43 | |||
bfd51097c9 | |||
a21e3cd842 | |||
0f298cf48e | |||
4b074b8dcf | |||
2c79853ffe | |||
72f57255f0 | |||
1053bc8bb0 | |||
4835e6fcb9 | |||
7ec02a1620 | |||
10993cc6ef | |||
81409369bc | |||
edb8590da8 | |||
3a7bfd28fc | |||
36fdb4ee2f | |||
b06f772647 | |||
012cc740d6 | |||
1407cff49d | |||
3331e1c152 | |||
591f48856d | |||
479b9691fd | |||
0e48557b48 | |||
3fae6f06dd | |||
7639c24bfe | |||
39fd1c3ab8 | |||
abf9dbae6d | |||
98062f830a | |||
c259347917 | |||
9c4558d891 | |||
9e7e2948e3 | |||
43430da25f | |||
eca7ac21a0 | |||
bc463f6d0b | |||
ec2708a1fd | |||
082922de01 | |||
ea02a7c70b | |||
ab7e25bd52 | |||
d4876dd25e | |||
89ee0bbab4 | |||
06ae882064 | |||
6517fe7515 | |||
d510aad2ab | |||
3db297de95 | |||
8688f26f15 | |||
85d38e7af2 | |||
0448348154 | |||
ceab4f1ffc | |||
3781b8db09 | |||
7a450c526c | |||
c1e8ea0e4a | |||
f248a33eaa | |||
67fb4e7007 | |||
0a41052f3f | |||
a7763a08dc | |||
fcfb471a8a | |||
b9e383130e | |||
cd2159b873 | |||
e492d5e0cf | |||
9a0f6490ba | |||
5183b44d8b | |||
156d86835a | |||
eab4397b0f | |||
d808b999c6 | |||
603b345405 | |||
682534f468 | |||
42eb43f713 | |||
0817b58b9d | |||
9ab766375d | |||
6c2799fe53 | |||
ef81a575cd | |||
cce0d94fbb | |||
22b5203334 | |||
d4be5abe67 | |||
9985a02efc | |||
41c2c60ab0 | |||
f285364f46 | |||
1c5e9b7fe3 | |||
12cc501e25 | |||
49118b8bf1 | |||
09dfea7dea | |||
00bd469f8e | |||
18e7e56a6c | |||
34d14a720b | |||
c4d7f9924f | |||
80d6921a66 | |||
3c95144b83 | |||
84ad155ab8 | |||
330a5ddd0f | |||
3b2f1d35c4 | |||
0f1036b0e1 | |||
86935f10a8 | |||
1078c42a14 | |||
09cf973712 | |||
5af749a226 | |||
f84b86a752 | |||
ca7873eda7 | |||
f87ebaf214 | |||
a9802eb6a7 | |||
5d5a68cb3e | |||
c6b1f5053f | |||
1d2e01c8cd | |||
0c5c18a767 | |||
6826ba05e7 | |||
053ce88743 | |||
4a216c57d4 | |||
03cec7fd5a | |||
1238001add | |||
fa1c077fdd | |||
8a7c3390f5 | |||
2302aee819 | |||
a72866ee6a | |||
0f7a3dba87 | |||
5decf18eb5 | |||
c318760398 | |||
629eff20dd | |||
f6e508ca14 | |||
588ab86abb | |||
387629372b | |||
0a01700e3e | |||
59504deb7f | |||
8ee660c238 | |||
176c106427 | |||
ed4fe56e7e | |||
310cd54aa0 | |||
3217b4ac90 | |||
7bf1949061 | |||
51f9d6d421 | |||
ddb32c65fb | |||
c5c158e983 | |||
f83007e038 | |||
2b9a368b18 | |||
6ad6974452 | |||
308923448b | |||
04ad7de2e1 | |||
54563b0b42 | |||
593779b54f | |||
34d3704680 | |||
613f90bcf7 | |||
6ff500f7cb | |||
c79e33896e | |||
68b15aadca | |||
819504f08f | |||
e65ec2a589 | |||
1bc355b8fd | |||
d76164679f | |||
efebecfc67 | |||
7b64586c87 | |||
0fe15b8e1d | |||
a1cb00b5a3 | |||
5041d819a9 | |||
02ab6eac62 | |||
d7feab116f | |||
4f9e13d0f6 | |||
d0b0e6a58e | |||
a12f898096 | |||
c921ecca05 | |||
975378b224 | |||
915e003355 | |||
51e45d128a | |||
57650ef058 | |||
dee6e16e6c | |||
c860674613 | |||
33b7f08d5c | |||
66bbe21a87 | |||
51995cc428 | |||
a3e3a305ce | |||
15facc72b3 | |||
3839c8d1c0 | |||
d5edcbc6e1 | |||
eb97ef4cb2 | |||
9c38e1e191 | |||
7c3d3b4128 | |||
367cea4b1f | |||
a63bfeaeec | |||
41672dde64 | |||
3b18cb7eca | |||
c9ce1751c1 | |||
4ba40b340a | |||
e3be1d1a04 | |||
6fa2a416be | |||
fdb54c315b | |||
c7de4e46c1 | |||
22a7757461 | |||
0bacbbc553 | |||
fbdc535287 | |||
03d8314842 | |||
fe4d98f0df | |||
b1d60122a3 | |||
64ec9f6a00 | |||
2d6f71dc12 | |||
c9e20c5d23 | |||
381f494754 | |||
506419964b | |||
35bb8c5348 | |||
79fe799aeb | |||
2878a6487e | |||
d4722e0d2c | |||
9655e79d26 | |||
d1a2e24f0e | |||
086381d958 | |||
7187f6f714 | |||
e10e05166f | |||
b0f8d84a7f | |||
0e9ceba057 | |||
fe3059f0ab | |||
bd566f52cf | |||
b7e0dabe61 | |||
2d2348f671 | |||
b28eb708a4 | |||
bf9c4b2346 | |||
d33aa097fe | |||
8673c232b6 | |||
d3ea5d2122 | |||
370d2555c7 | |||
5332cee3e8 | |||
1246e1c498 | |||
d6b0b1b93c | |||
1e0c970c95 | |||
db9f49c7d4 | |||
1603353ae8 | |||
6753d23309 | |||
ca5755b0fd | |||
2c8223274d | |||
f0dd09cf9c | |||
4746d9eb80 | |||
99401c5639 | |||
58578d9020 | |||
af575d6c95 | |||
e9c8748c0b | |||
08409d016b | |||
42bfbfc60b | |||
c7c087d964 | |||
89764c12e7 | |||
bd45d5483f | |||
328d7d0008 | |||
cca5bef8c1 | |||
ce4874d825 | |||
9b408b67ef | |||
c3bf100082 | |||
b282ccd890 | |||
f38b741813 | |||
3a899d52d1 | |||
a2567b0ee2 | |||
4b0019c732 | |||
5d21738410 | |||
df81006b42 | |||
2c7006e9bd | |||
b1caa8d5a3 | |||
8b2ffada10 | |||
0998738e94 | |||
c04062bbdf | |||
0c7a3a3a39 | |||
f364a83f4f | |||
9dabc75866 | |||
2c185ea76c | |||
39e859c368 | |||
2cfe5e678a | |||
d48991f71f | |||
dfbe3c4eb1 | |||
b8170a544b | |||
4e7f92ec89 | |||
292683268b | |||
dc14abd4d3 | |||
dd782f08f7 | |||
d57dc9a8a2 | |||
4e463d57ce | |||
e0c0cc8b63 | |||
cc50d47376 | |||
4da7548caa | |||
91a676cb36 | |||
48a32fb3b8 | |||
845b45a57d | |||
7b7a620999 | |||
82217d5ebc | |||
b95ec70d7d | |||
aa3d3670a4 | |||
8198c83982 | |||
75ff7987b8 | |||
9c87685c02 | |||
ce2bb85440 | |||
43fdff2292 | |||
06525adf3d | |||
cff4210dfd | |||
d855c5de50 | |||
f1a738340f | |||
9827c48527 | |||
367d68e552 | |||
1498ed361e | |||
91bc16ce05 | |||
861a1e26d7 | |||
a5b2f9a5e9 | |||
9550484037 | |||
b33284bb8e | |||
ce2694e8fb | |||
44073732e2 | |||
fef591412e | |||
f191e50b14 | |||
3379432e5f | |||
bb9129b61b | |||
0fc3029aaa | |||
d8c8586ccf | |||
38a4728283 | |||
7888705b01 | |||
31938f49d6 | |||
c95ed2ea96 | |||
b5ed247a53 | |||
22aff49747 | |||
e4430f05e4 | |||
1047691c64 | |||
f3180b3f6f | |||
616866cc9e | |||
58512b8230 | |||
ca4555c496 | |||
bc99bc7206 | |||
8f2dc67430 | |||
1420c773a6 | |||
888ef37808 | |||
690b40ed77 | |||
986de4c1d6 | |||
01da32364f | |||
8b1abc08db | |||
69e56f8f6b | |||
b611d0238a | |||
c987a9735d | |||
3b9549c2c1 | |||
2dcc9b7a1e | |||
3e54b5d544 | |||
8845ce6e1c | |||
ff189e796c | |||
89c07ac969 | |||
a8e878f894 | |||
1f8f3eb4d9 | |||
8fd2a05bf9 | |||
002d057c92 | |||
ab44488e4c | |||
653ffbc82e | |||
95fd0291e3 | |||
2a269ff1a9 | |||
83ccfb4596 | |||
e968828916 | |||
ed85a2b82b | |||
e692e21dc9 | |||
662fe3ebc2 | |||
1bf8fd92e4 | |||
4dd8a6421a | |||
884b285bf5 | |||
cb340152df | |||
299a44e7eb | |||
40e5bcbdbb | |||
d328e78727 | |||
1bcb9b24b6 | |||
3c1c130bf0 | |||
df3442563c | |||
331b1fa742 | |||
b97a53177e | |||
633b71ba19 | |||
f3dd42143d | |||
7c79f5d5e5 | |||
af5c0bd8a7 | |||
c07bfe34ab | |||
49681415e2 | |||
190e8c01b7 | |||
6ae86f7d81 | |||
0aeb3ca75e | |||
1d3e12abb7 | |||
5e8428ef6c | |||
19e3064529 | |||
f9dbd74ad8 | |||
ff837cf66e | |||
e0914c358e | |||
0e9bb23c7b | |||
7ff5d36f07 | |||
5a3eab0c7c | |||
c28f707f55 | |||
ef96c88719 | |||
faa2435e33 | |||
0537a221d3 | |||
99c5a1978f | |||
d106f483a1 | |||
dee84e70ae | |||
09995b77b4 | |||
06894f9f0b | |||
73943b1a08 | |||
b573dab05f | |||
a766eca283 | |||
a65edbef92 | |||
7479aa235e | |||
4167cd955b | |||
d1bd893a7b | |||
2467856011 | |||
d32b4e9f24 | |||
1acd5caaa8 | |||
f69b757305 | |||
d2db41bc89 | |||
f3b4377ee1 | |||
551a8091a9 | |||
f994590ad7 | |||
8371b8f806 | |||
5d04f8db89 | |||
06de347373 | |||
2bf2eb482e | |||
a93666cd36 | |||
dbb7eb3d88 | |||
39169f0450 | |||
df71308664 | |||
e393f82eb7 | |||
8480a204ea | |||
197be5f60f | |||
5621e9b390 | |||
485d785e0b | |||
8d71d496be | |||
738bae46d2 | |||
d519228efb | |||
72c404c4d4 | |||
d2e3547a2e | |||
8d9790fd77 | |||
cd91a6b2a4 | |||
e165c1805d | |||
292b0a81c0 | |||
b9e9c07d95 | |||
837bf9eafe | |||
cfdbef05c5 | |||
47b10e9771 | |||
1b5a2ddef3 | |||
c161649ed5 | |||
c9b5c03e1b | |||
c4c04d7ec5 | |||
b4e03fa969 | |||
1cdcf1cb0a | |||
56b6992ca8 | |||
2beaea4a86 | |||
2dc97b160a | |||
a014918c0d | |||
fb9a4eb87a | |||
cd83c48526 | |||
5b2766ddfb | |||
f912b01137 | |||
b0db4e4fff | |||
649f76fb06 | |||
91408cbdce | |||
97c1ba2d02 | |||
284802bfa5 | |||
48b6e0693e | |||
67ea2f3717 | |||
e9e535cb94 | |||
7822b5c3ac | |||
767bd05ce1 | |||
36ebe19cd7 | |||
943ea957a2 | |||
04a3673366 | |||
1dfbe73b73 | |||
87889bb322 | |||
aa0616d7c5 | |||
611ff6357e | |||
91d7a0ab98 | |||
f5661da595 | |||
d867f9f36e | |||
55d92fc9f2 | |||
2e2d3c39e6 | |||
3cd01acb73 | |||
02c0ddb3d3 | |||
ce397f5858 | |||
3f56ce206d | |||
8a2308b411 | |||
04cabf40b5 | |||
4e0c4f6f98 | |||
75bd235eb2 | |||
05236b093a | |||
260ebe512c | |||
c2dab16c8c | |||
945d455f33 | |||
c8f8f6ff34 | |||
0d4f597a59 | |||
775047fbc2 | |||
1e4b43314c | |||
b365817c99 | |||
bbb04774d1 | |||
1823e5e641 | |||
4d2dc1c8e8 | |||
6986f90bf8 | |||
b43ebd2486 | |||
611f991fdd | |||
7bf3ea5200 | |||
490727b401 | |||
49f4f3398d | |||
b84682fdc9 | |||
b9491b269b | |||
b70cbb28b2 | |||
673c14287a | |||
b4a0ffdbbd | |||
3b2e5bded2 | |||
67eb3cc140 | |||
5a683149ab | |||
b75ad1ca5a | |||
552ab31559 | |||
4abfde4047 | |||
6ecfedba37 | |||
43883a90d2 | |||
3930113f00 | |||
029198c213 | |||
493788f4f8 | |||
028776de88 | |||
705de68aa3 | |||
eb96a74e32 | |||
614f34c6b4 | |||
f77a3c7f56 | |||
6de81d41d2 | |||
7ac9dc5542 | |||
2195c2fe98 | |||
3f35e927dd | |||
5ec659513b | |||
1039a4b7a0 | |||
88899c1233 | |||
d429514a3a | |||
b2c6fcbb73 | |||
3b1e030b39 | |||
e097a1caeb | |||
d6b09f8bab | |||
6d46344171 | |||
24e807b238 | |||
fdf6f5d51f | |||
4b938a02e7 | |||
44a5740a04 | |||
8d73b2e838 | |||
e1fc6893b4 | |||
7487ab8848 | |||
e675416b8c | |||
24a133fe67 | |||
0570feda6f | |||
b206665c72 | |||
8a6fb132f5 | |||
6992ca8b98 | |||
fd916a7646 | |||
90cd68900e | |||
3f865edb4f | |||
2e8681de2c | |||
2d85b98c20 | |||
d28d6efb79 | |||
43d84a5f07 | |||
e4d57f62bb | |||
a974268e7b | |||
1695af7011 | |||
682c4cd0b8 | |||
0f6d039391 | |||
d6233a8798 | |||
4f12e81dbb | |||
ab612d0088 | |||
3fa7bb9dc5 | |||
22b3d4d70b | |||
bd6c588c74 | |||
6c202e8f1d | |||
24e6750529 | |||
af7ce8e18e | |||
c73f0eeeb5 | |||
c68769cf7f | |||
3e639a319d | |||
1bbb79f5b1 | |||
84e6991374 | |||
5d1796bb6f | |||
bfba732f76 | |||
738c5ed14e | |||
beed080390 | |||
3624d66c12 | |||
2cca2781fd | |||
31d485299c | |||
a39f667c2f | |||
5283fc923e | |||
c57552f4e9 | |||
96b4c6b219 | |||
51911bd9a8 | |||
1f5926e4e9 | |||
d6a02a13ad | |||
e282491798 | |||
2b0dfed012 | |||
9d80aff977 | |||
a0724dc009 | |||
8c820bb237 | |||
3fdc964eac | |||
597662d0dc | |||
17c80c29e6 | |||
5d0bfc63fa | |||
0c449f8b8e | |||
36b6baa33e | |||
2c049878c6 | |||
81c58c1796 | |||
36a3edf612 | |||
4b6fd3d387 | |||
f777696e14 | |||
c9c181c14a | |||
a62b7a4374 | |||
9d7a9c9895 | |||
5d6a1c5e35 | |||
c48266fdc4 | |||
895d54d36d | |||
ba0e1a3aa9 | |||
6ec665db50 | |||
7f4c52cf42 | |||
37728e38c9 | |||
18b4a2427b | |||
3102970540 | |||
c679091afd | |||
91cdf85772 | |||
aab8b10adf | |||
5bcfe1ec72 | |||
4209c291ba | |||
7c5dc7fa55 | |||
c6dfb8744a | |||
6e0ca92041 | |||
2f7eb56790 | |||
8c98ef7328 | |||
45997fd1d5 | |||
6a3e5ec620 | |||
18cbf3d253 | |||
4df6a6f47b | |||
5542406f3d | |||
a9fceae181 | |||
c79ff0dc09 | |||
e2fc5c6957 | |||
5667a6647f | |||
b70d616083 | |||
75fa2b1809 | |||
66d9017d58 | |||
53efb7119a | |||
8b946bb56b | |||
8ed34e3edf | |||
d8fef53aef | |||
6af82f2a9a | |||
36b2547ca4 | |||
72e96cdd23 | |||
a2ba9bbdb1 | |||
f6d9a6917f | |||
2e91890401 | |||
1956068698 | |||
855cae0a45 | |||
ef3a12f01a | |||
37bf750ab9 | |||
090a790a9d | |||
8ef3bb3d82 | |||
388019249d | |||
91d1364832 | |||
2ec1d8484f | |||
9a01fdf57c | |||
deec84713f | |||
0d028122a6 | |||
4998f86efe | |||
839bd51bc8 | |||
936f2bb317 | |||
0cd774273c | |||
fe391ff29f | |||
001b127258 | |||
7c00a5165f | |||
e1c3e2c1c7 | |||
e9b3577eec | |||
3622501471 | |||
b7207fd29f | |||
4dc1241d2f | |||
c59603d31b | |||
3ab149a399 | |||
99f28519fb | |||
05aa88b4e8 | |||
887f953efb | |||
5e16c42e4e | |||
2cea7cdb30 | |||
e60da8e8ff | |||
be12995753 | |||
c30419107f | |||
2cacded182 | |||
ec22a1dafc | |||
434bf13be9 | |||
236df32f30 | |||
28575dbdae | |||
5b9d669d79 | |||
b2f4fde7e5 | |||
9eefe1e935 | |||
b91f041ad7 | |||
ba96f72899 | |||
5d322245d8 | |||
47712a39ac | |||
6b16907e40 | |||
18146daad8 | |||
0c326f989e | |||
e0a499dd0f | |||
0f862124fe | |||
d00be4ceee | |||
ec8354860e | |||
f9144f2fbf | |||
5d2ff5e648 | |||
ce475d2cd6 | |||
72bd1fe91b | |||
747d833392 | |||
3427464de6 | |||
9ca625a64e | |||
9e87fd9b13 | |||
5b6ed48ec0 | |||
96f6865835 | |||
fa50f9f246 | |||
538b4b10d7 | |||
bdb3e26d07 | |||
ec87600e80 | |||
0624f46e67 | |||
ece1198dd4 | |||
a83c88e886 | |||
8bbab31872 | |||
8c6922ac5f | |||
6b67f399f6 | |||
a9598633b3 | |||
1fb2672b67 | |||
4308ce6347 | |||
32b095efbd | |||
eb4bdfcefb | |||
fc6554cabc | |||
058590f69b | |||
576984badc | |||
9825fcf97b | |||
1ed96d72b2 | |||
a29935abb3 | |||
e92a5da5a5 | |||
f08e0299ef | |||
9757435b09 | |||
80fadb4580 | |||
8658c23974 | |||
0264cc9030 | |||
bd5b6b32b5 | |||
dc0a1281bf | |||
c20c697126 | |||
44e7110c9a | |||
c860c49c6b | |||
b16e66d39a | |||
3b06f0b83c | |||
0bc6c23ac9 | |||
17e63b054c | |||
0fae0640d6 | |||
d054e12952 | |||
dc60c2b478 | |||
b59aa1fb69 | |||
54a21bfa7b | |||
50f55877f8 | |||
f9ff262318 | |||
91ba76f2a6 | |||
ec97bc2f81 | |||
fba209ca7d | |||
b91b242a1a | |||
38186c8f75 | |||
1b3aefbbce | |||
c03511b971 | |||
78e7599a8a | |||
dc871cf1eb | |||
e98b9d0af5 | |||
2a09d5baa6 | |||
41e071efe5 | |||
e8e239616f | |||
1feb317f8b | |||
09668453d0 | |||
5842e25205 | |||
a2e7fa8b7b | |||
30ccf1b334 | |||
5219791673 | |||
bf485d8bce | |||
cc97a19d3c | |||
38c02b44b9 | |||
04a596899a | |||
ee1ed1bb82 | |||
2b39d28e99 | |||
01b153488a | |||
8cb503d8bb | |||
efff25a87c | |||
6e2583ad92 | |||
af84bcf945 | |||
3dc429415b | |||
ec9dd25631 | |||
2bda87d5a7 | |||
a7a816e0a7 | |||
3d9d722cee | |||
289a8e7b40 | |||
7d3aa33c25 | |||
0db1314595 | |||
68641626aa | |||
5b9fb403c9 | |||
a4114b96fd | |||
de184ed139 | |||
04c342ec6a | |||
27ce28027d | |||
f8a54bde19 | |||
3acfdbe8f7 | |||
d9fed57c89 | |||
46e7e9be82 | |||
d87d4eb232 | |||
88ea451f81 | |||
822ec4aa53 | |||
7b0b07933f | |||
7fe8573df4 | |||
c180292358 | |||
a3fa48dcbe | |||
445e4301d5 | |||
736da22bba | |||
f29c64cd70 | |||
aa4b4b9d2b | |||
1112fc8544 | |||
9b361ac445 | |||
0ff423fc57 | |||
efe3bd2c05 | |||
f112baac48 | |||
707f616498 | |||
ed2feb3ff7 | |||
a17b1b99c0 | |||
27bc32f2f3 | |||
b535054e13 | |||
97a9a6090a | |||
8b8e2c88c1 | |||
9d7ee30c15 | |||
4ee144533a | |||
0f2a983bb7 | |||
8fd2f9090e | |||
8770d7eae0 | |||
c59ef24acf | |||
85aa2fb083 | |||
434b9fa0d1 | |||
56116ad8c2 | |||
c0ef19a281 | |||
9804e5b7d9 | |||
2f33186e58 | |||
0347c56c96 | |||
e77409e57a | |||
615ba94559 | |||
ce0596d5b1 | |||
35b6926e4f | |||
76925fa3bd | |||
dbdf36d85c | |||
60aa8c57a4 | |||
001070f677 | |||
c6f2d4948b | |||
8699c82614 | |||
1d7eedd463 | |||
796a231f54 | |||
e1fcad686c | |||
ffa03f2b83 | |||
54fb91ba8e | |||
e498e2113f | |||
f42ac71fe0 | |||
74f2fd06cc | |||
143a0dfc47 | |||
fdb0097934 | |||
0dde4162e6 | |||
844bae18ba | |||
9e4d5c0e61 | |||
9b8d3eb688 | |||
8478bfbddc | |||
d6bb5f6a4d | |||
e9fec9354b | |||
f9f0e6d0a2 | |||
3bc0be1cbe | |||
8d826cee93 | |||
e853d9a40b | |||
15bf94b479 | |||
6314f33d8f | |||
5fa0376f58 | |||
552dd189a5 | |||
57144f3e6a | |||
0454639db8 | |||
c32b451733 | |||
2f4765665d | |||
bff79cdae8 | |||
4bddf8ae0b | |||
ae79deff39 | |||
e3aeb267f8 | |||
c5c26c440d | |||
77971624b4 | |||
f5621c5082 | |||
3fa7fe9733 | |||
c97d07e10a | |||
567c328331 | |||
3aa982529e | |||
0c07f9ff96 | |||
f0055ccbfe | |||
693cc828c2 | |||
688dd23111 | |||
e38db5eb44 | |||
817f531619 | |||
53623da2eb | |||
4910266d9b | |||
24ae66df6d | |||
228bd980db | |||
f161a2dfc9 | |||
abe1dc676e | |||
9de57a5d5a | |||
2cc742c3ed | |||
5bcfe025d5 | |||
6dc6ca7713 | |||
eabcc96a99 | |||
28b6675979 | |||
413ad6b0e6 | |||
a7a7e96188 | |||
796dbc5d2e | |||
c86845078c | |||
89dcceefee | |||
bacce17990 | |||
e61e950713 | |||
244209d3b7 | |||
dbe0a8240e | |||
7e3e08532f | |||
1d4190734d | |||
96cf1d60c2 | |||
3aa33378c1 | |||
747bd0c5a3 | |||
ea7b42810f | |||
19022baa27 | |||
e8248f5005 | |||
f8178b7165 | |||
79b5d9748d | |||
b53ed94e8f | |||
df84a2fcd0 | |||
25e7dea370 | |||
90919ebf6b | |||
76078deb3f | |||
1b95a03d2e | |||
108039de08 | |||
addd2e6d6a | |||
5c38d5a6c9 | |||
69489dd19e | |||
3fce0e8e45 | |||
35fb332c2c | |||
1b5309be05 | |||
d2a1025b3f | |||
0a8f79f0e3 | |||
18e4c2ac63 | |||
90c2e08489 | |||
598ef67c4e | |||
1b9d870b91 | |||
68f67b7c8e | |||
d2f0c251c0 | |||
2b2f34b3f1 | |||
4e680479da | |||
d1b93e0705 | |||
4382def62f | |||
952a56c537 | |||
67aead214b | |||
50f45a50a7 | |||
6b326c3705 | |||
919ec3af01 | |||
ca5a301a4f | |||
ae76a6ee1a | |||
5cbecb3599 | |||
5a34e1de4f | |||
c810694e07 | |||
ca866d48e6 | |||
f1e77499e2 | |||
9007db1485 | |||
85c998e500 | |||
8296f8229e | |||
059ae3a80e | |||
67e242c441 | |||
e23f3b4875 | |||
06ea9af733 | |||
884818f518 | |||
3f39bd0f7b | |||
48cce6435b | |||
777e08c8b6 | |||
8c4b0b7c00 | |||
dae8b25374 | |||
2ae293444e | |||
0f11d3566a | |||
fa70d439c3 | |||
0010581405 | |||
1d659e4f8a | |||
509f00c5e2 | |||
aeb3241abb | |||
8909df3c88 | |||
1cffcae36b | |||
d2ee5b96ad | |||
0506a5915b | |||
91ef3fd0bc | |||
79f5484f87 | |||
6afd2c4b97 | |||
06b09f89de | |||
bd0eee6aa9 | |||
5bc13c16dc | |||
626daeb86e | |||
a92913da4c | |||
f0f363e8c3 | |||
7839c0fec3 | |||
4d24d65c1f | |||
ddf761b1f8 | |||
2814fe75b1 | |||
7316c82ef3 | |||
e04646bd37 | |||
8f8022347d | |||
acc0ab66a3 | |||
5a6acf1d85 | |||
ca45194c30 | |||
102506ebe8 | |||
d06f1c4a30 | |||
c732c1c038 | |||
4aa1bba575 | |||
9d3925eb20 | |||
80fdf4e917 | |||
35a86e603b | |||
8f7b31aed3 | |||
0f5a0b6b1b | |||
4cf3906ed2 | |||
57875586cf | |||
ad8ec011d0 | |||
0d93b86a56 | |||
63712002e2 | |||
67af1a17c1 | |||
9cac546547 | |||
3ffb321f46 | |||
14ea6d8d0a | |||
8e0dbf31ba | |||
5187bf1eae | |||
99471d8e1b | |||
012e999354 | |||
bdd9900d0d | |||
c71b485083 | |||
a78d34ab4b | |||
255ebe7efb | |||
5f7a761e42 | |||
09548358fa | |||
df381c37ff | |||
31e96b416d | |||
53b0f7b579 | |||
45deaa3a87 | |||
0c8eabcdf6 | |||
f9571740ae | |||
eb2af2b5fd | |||
ded00300b4 | |||
811819af69 | |||
1804c852bb | |||
3ec602865d | |||
0c0a25b038 | |||
208192f445 | |||
d0f635e30c | |||
20b2f7dcb1 | |||
cf66951818 | |||
c6f41cc8fa | |||
45a579403a | |||
74a57abfb4 | |||
380783c1ba | |||
c8843a736d | |||
e69fefda62 | |||
513da3b743 | |||
7513d42e9e | |||
8872437caf | |||
712c77a4b6 | |||
38cef14cf4 | |||
05c3b0d391 | |||
854090e9d8 | |||
f035815f7a | |||
df4302dda0 | |||
31f117e74c | |||
890f40b2ac | |||
3ac8083faf | |||
249319f76f | |||
efe87060b4 | |||
afe3ff57cf | |||
6bb1505d3b | |||
a1c8e3eae3 | |||
aa171bbaa6 | |||
845b70fe0c | |||
82b1eb7c18 | |||
4bd27ea1d3 | |||
d0f6be3161 | |||
7764257e41 | |||
af0e72ac4d | |||
0534440695 | |||
c2fa2d0c5b | |||
887017b54c | |||
3a4f5a2f1b | |||
3fb4643742 | |||
a5e3bc9b85 | |||
8a0c3f10f4 | |||
e1d808a284 | |||
e755051ebe | |||
d7c3ffa4de | |||
cba3b249dd | |||
32f250003e | |||
e004b0e6e9 | |||
a5c5917a5f | |||
cbd24946b6 | |||
9b4842931a | |||
e04cf132cc | |||
7d237b4cf6 | |||
3cbfd09722 | |||
0ae774dd68 | |||
2884df873e | |||
d4d1424c4f | |||
33827f9aaf | |||
30a666c833 | |||
9a00621fa4 | |||
46bc479884 | |||
6ab6abf4dd | |||
0c6a9ff2a0 | |||
aefc5b5317 | |||
25682fdea7 | |||
9318099845 | |||
fdf38a952d | |||
fb40ab1f00 | |||
3499ed7bb0 | |||
b05906a3c2 | |||
61d5f46295 | |||
9ebfccd8f6 | |||
4fb3e86e4d | |||
837517e94e | |||
f47ec65b8f | |||
6fede7f524 | |||
bd0c18b2e3 | |||
fba596c78c | |||
61f2b49022 | |||
e71a1a5c4d | |||
683ce3254f | |||
df555731c4 | |||
641fc0cae9 | |||
5ab1d6896a | |||
0ae2d92fcd | |||
26c8201e03 | |||
37521c69a2 | |||
43383a5b3c | |||
bfea3e4dd6 | |||
35b02a52e1 | |||
8e3e566915 | |||
968b9a0304 | |||
c97f0f3d22 | |||
65b1124d81 | |||
89034e1f9d | |||
9f2fa6a8be | |||
19cf8787d8 | |||
a80c34c1df | |||
ab8900f910 | |||
ce2d0b0e12 | |||
87d98781a9 | |||
79dc95dd66 | |||
c6533202f7 | |||
b5dc9bc0ba | |||
79891c6677 | |||
68aa1aea8e | |||
4ffaf4128e | |||
801ca47a0c | |||
43f5062169 | |||
7ab4dd7f4b | |||
71c0104236 | |||
a608d21571 | |||
935ddaa0b2 | |||
945e7b75fd | |||
5e90780590 | |||
a8a21ea7ce | |||
23444e4b81 | |||
a3ea1f9429 | |||
78d4b6d8a7 | |||
3e3399adc6 | |||
1e554dd0fe | |||
388e7088e1 | |||
e65289cd0d | |||
c4d68a8352 | |||
7be0a93251 | |||
175f47293a | |||
27936fce04 | |||
592680302f | |||
55318cf14b | |||
83ead0c304 | |||
38ec55bc72 | |||
c4f97ed65e | |||
78a426e9ac | |||
928b4bbbe5 | |||
d27c465371 | |||
4d62f63c71 | |||
f4039b085a | |||
53ed10cfc8 | |||
0859dbe57f | |||
42bc4bb1f4 | |||
caead8a3a4 | |||
7394c7997b | |||
0298e4ab4c | |||
e3a5cdbbc2 | |||
6ae46abac0 | |||
615a5f3c39 | |||
6812dc1db8 | |||
41595cafce | |||
d6c4e411be | |||
6ca797ec1f | |||
8655988c66 | |||
de5f2940ce | |||
1933e6239b | |||
8aec1e2eb6 | |||
def30c5903 | |||
193f0bbc42 | |||
b7a3b7bf05 | |||
a2bd45fa9b | |||
fd297118f9 | |||
7171edad24 | |||
d8466333f3 | |||
a5e4d586eb | |||
28a1c22438 | |||
74e238322d | |||
1f3227409b | |||
afda1da9c3 | |||
f2857e8f97 | |||
4802b1e2cd | |||
0328304f04 | |||
06d2db0046 | |||
0539610219 | |||
170be8f033 | |||
ca0bb1ab76 | |||
cdccb51456 | |||
870ecb847f | |||
8ba493c60e | |||
f3affff5be | |||
5941a52a0d | |||
04e6beb43c | |||
1284c7ace0 | |||
63414f0348 | |||
c8f22fdfd0 | |||
7737bf5212 | |||
4340f70d72 | |||
6dbd8a6d1a | |||
076871fe44 | |||
be753d7a1a | |||
e3f02553fd | |||
767ef8c489 | |||
482787fbc3 | |||
b2d72f90ce | |||
dd181a90e1 | |||
19faa352e3 | |||
ffda7f6326 | |||
8ebacf4c10 | |||
a02cc25844 | |||
8aeca5b433 | |||
7b4855d7cf | |||
803d7ff282 | |||
a1c724f866 | |||
96609e9173 | |||
f5518739e2 | |||
e7c8d28b99 | |||
dff357a658 | |||
cc271de7df | |||
a7485ab5a3 | |||
7133736702 | |||
2313d82369 | |||
1b42d99e66 | |||
d709f46183 | |||
97c1676bcb | |||
02b92ac3fe | |||
29eb1d5dc5 | |||
a87fc68cfd | |||
bc1cf64df4 | |||
b607d7b223 | |||
4e00eaf9a3 | |||
90cc71d14d | |||
554a3a6b0e | |||
8505e8a1ca | |||
54ec878698 | |||
ea4606fe79 | |||
96de87fdde | |||
55d571ffec | |||
ae347c4fa1 | |||
e93beb7c63 | |||
018098b8ef | |||
1e2fb4bea5 | |||
171f0d2671 | |||
175cb0817e | |||
3b46acc285 | |||
d31ce49e77 | |||
8937c4bf2a | |||
2902a708f9 | |||
c1210b1c04 | |||
71038c311f | |||
70a8ab1d1a | |||
f3c4a26483 | |||
9a1e1a92ca | |||
732eddd1b9 | |||
2caa6ad975 | |||
d3e0161a6b | |||
aabbdc1c1b | |||
bcfc7630d1 | |||
3aafea0d98 | |||
79f8e88e5f | |||
34b7081303 | |||
e0cd71069f | |||
3b7daafad7 | |||
378c5a0d4e | |||
6c62c1f362 | |||
3daf287de8 | |||
9a4cd11748 | |||
c0350702fd | |||
55880844a5 | |||
729282c0c4 | |||
d603c3b5cd | |||
5cda1ec703 | |||
ec3756a69f | |||
0b49fa98f9 | |||
226c7eb8e3 | |||
be262c6a70 | |||
a374f00613 | |||
fcdf837f33 | |||
febc0a5237 | |||
a19140e186 | |||
e0b25cdcf9 | |||
e332c8bc27 | |||
7318632db9 | |||
1b38a6478b | |||
6ceea60c92 | |||
fcaebb4416 | |||
0be3beb30e | |||
5e51c6abef | |||
5e953b0857 | |||
c76c80043f | |||
3a49d6d28f | |||
94e34ff366 | |||
af27c76b2c | |||
60336c9555 | |||
a85b7aa9f8 | |||
228e6d7d03 | |||
31531ee882 | |||
368c2073b2 | |||
757df8c726 | |||
c6121cb31e | |||
eecab472eb | |||
b71631d2ec | |||
3ec78e27b4 |
48
.gitignore
vendored
Normal file
48
.gitignore
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# Just to try and prevent some noob disasters.
|
||||
# Use git add -f foo.jar to ignore this ignore list
|
||||
|
||||
# generated release files
|
||||
*.exe
|
||||
*.[gx]z
|
||||
*.bz2
|
||||
*.[rwjt]ar
|
||||
*.sig
|
||||
*.su[d23]
|
||||
*.deb
|
||||
*.zip
|
||||
*.torrent
|
||||
|
||||
*~
|
||||
web-fragment.xml
|
||||
web-out.xml
|
||||
*.out
|
||||
|
||||
# Temporary/build dirs
|
||||
build/
|
||||
pkg-temp/
|
||||
classes/
|
||||
dist/
|
||||
/installer/resources/locale/mo
|
||||
/tmp
|
||||
/apps/jetty/jettylib
|
||||
*_jsp.java
|
||||
*.class
|
||||
|
||||
# Debian-related
|
||||
/debian/copyright
|
||||
/debian/changelog
|
||||
.pc/
|
||||
|
||||
# Build property overrides
|
||||
/override.properties
|
||||
|
||||
# Reporting
|
||||
*.fba
|
||||
sloccount.sc
|
||||
/reports/
|
||||
|
||||
# Don't allow patches
|
||||
*.(diff|patch)
|
||||
|
||||
# but allow debian/patches
|
||||
!/debian/patches/*.(patch|diff)
|
25
.mtn-ignore
25
.mtn-ignore
@ -1,5 +1,7 @@
|
||||
# Just to try and prevent some noob disasters.
|
||||
# Use mtn add --no-respect-ignore foo.jar to ignore this ignore list
|
||||
|
||||
# Temporary/build files
|
||||
_jsp\.java$
|
||||
\.bz2$
|
||||
\.tar$
|
||||
@ -14,18 +16,35 @@ _jsp\.java$
|
||||
\.sig$
|
||||
\.sud$
|
||||
\.su2$
|
||||
.\su3$
|
||||
\.tar$
|
||||
\.war$
|
||||
.\deb$
|
||||
\.zip$
|
||||
\.torrent$
|
||||
^\.
|
||||
^build
|
||||
^pkg-temp/
|
||||
~$
|
||||
web-fragment.xml
|
||||
web-out.xml
|
||||
|
||||
# Temporary/build dirs
|
||||
^build
|
||||
^pkg-temp
|
||||
/build
|
||||
/classes/
|
||||
/classes
|
||||
/dist
|
||||
^installer/resources/locale/mo
|
||||
/tmp
|
||||
^apps/jetty/jettylib
|
||||
|
||||
# Debian-related
|
||||
^debian/copyright
|
||||
^debian/changelog
|
||||
^.pc/
|
||||
|
||||
# Build property overrides
|
||||
override.properties
|
||||
|
||||
# Reporting
|
||||
sloccount.sc
|
||||
^reports/
|
||||
|
202
.tx/config
202
.tx/config
@ -9,15 +9,46 @@ trans.es = apps/i2ptunnel/locale/messages_es.po
|
||||
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.nb = apps/i2ptunnel/locale/messages_nb.po
|
||||
trans.nl = apps/i2ptunnel/locale/messages_nl.po
|
||||
trans.nn = apps/i2ptunnel/locale/messages_nn.po
|
||||
trans.pl = apps/i2ptunnel/locale/messages_pl.po
|
||||
trans.pt = apps/i2ptunnel/locale/messages_pt.po
|
||||
trans.pt_BR = apps/i2ptunnel/locale/messages_pt_BR.po
|
||||
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.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
|
||||
trans.zh_TW = apps/i2ptunnel/locale/messages_zh_TW.po
|
||||
|
||||
[I2P.proxy]
|
||||
source_file = apps/i2ptunnel/locale-proxy/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/i2ptunnel/locale-proxy/messages_ar.po
|
||||
trans.cs = apps/i2ptunnel/locale-proxy/messages_cs.po
|
||||
trans.de = apps/i2ptunnel/locale-proxy/messages_de.po
|
||||
trans.es = apps/i2ptunnel/locale-proxy/messages_es.po
|
||||
trans.fr = apps/i2ptunnel/locale-proxy/messages_fr.po
|
||||
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.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
|
||||
trans.pt = apps/i2ptunnel/locale-proxy/messages_pt.po
|
||||
trans.pt_BR = apps/i2ptunnel/locale-proxy/messages_pt_BR.po
|
||||
trans.ro = apps/i2ptunnel/locale-proxy/messages_ro.po
|
||||
trans.ru_RU = apps/i2ptunnel/locale-proxy/messages_ru.po
|
||||
trans.sk = apps/i2ptunnel/locale-proxy/messages_sk.po
|
||||
trans.sv_SE = apps/i2ptunnel/locale-proxy/messages_sv.po
|
||||
trans.uk_UA = apps/i2ptunnel/locale-proxy/messages_uk.po
|
||||
trans.vi = apps/i2ptunnel/locale-proxy/messages_vi.po
|
||||
trans.zh_CN = apps/i2ptunnel/locale-proxy/messages_zh.po
|
||||
|
||||
[I2P.routerconsole]
|
||||
source_file = apps/routerconsole/locale/messages_en.po
|
||||
@ -33,16 +64,82 @@ trans.fi = apps/routerconsole/locale/messages_fi.po
|
||||
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.nb = apps/routerconsole/locale/messages_nb.po
|
||||
trans.nl = apps/routerconsole/locale/messages_nl.po
|
||||
trans.pl = apps/routerconsole/locale/messages_pl.po
|
||||
trans.pt = apps/routerconsole/locale/messages_pt.po
|
||||
trans.pt_BR = apps/routerconsole/locale/messages_pt_BR.po
|
||||
trans.ro = apps/routerconsole/locale/messages_ro.po
|
||||
trans.ru_RU = apps/routerconsole/locale/messages_ru.po
|
||||
trans.sv_SE = apps/routerconsole/locale/messages_sv.po
|
||||
trans.tr_TR = apps/routerconsole/locale/messages_tr.po
|
||||
trans.uk_UA = apps/routerconsole/locale/messages_uk.po
|
||||
trans.vi = apps/routerconsole/locale/messages_vi.po
|
||||
trans.zh_CN = apps/routerconsole/locale/messages_zh.po
|
||||
trans.zh_TW = apps/routerconsole/locale/messages_zh_TW.po
|
||||
|
||||
[I2P.welcome]
|
||||
source_file = apps/routerconsole/locale-news/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/routerconsole/locale-news/messages_ar.po
|
||||
trans.de = apps/routerconsole/locale-news/messages_de.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.he = apps/routerconsole/locale-news/messages_he.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/routerconsole/locale-news/messages_in.po
|
||||
trans.it = apps/routerconsole/locale-news/messages_it.po
|
||||
trans.ja = apps/routerconsole/locale-news/messages_ja.po
|
||||
trans.ko = apps/routerconsole/locale-news/messages_ko.po
|
||||
trans.mg = apps/routerconsole/locale-news/messages_mg.po
|
||||
trans.nb = apps/routerconsole/locale-news/messages_nb.po
|
||||
trans.nl = apps/routerconsole/locale-news/messages_nl.po
|
||||
trans.pl = apps/routerconsole/locale-news/messages_pl.po
|
||||
trans.pt = apps/routerconsole/locale-news/messages_pt.po
|
||||
trans.pt_BR = apps/routerconsole/locale-news/messages_pt_BR.po
|
||||
trans.ro = apps/routerconsole/locale-news/messages_ro.po
|
||||
trans.ru_RU = apps/routerconsole/locale-news/messages_ru.po
|
||||
trans.sk = apps/routerconsole/locale-news/messages_sk.po
|
||||
trans.sq = apps/routerconsole/locale-news/messages_sq.po
|
||||
trans.sv_SE = apps/routerconsole/locale-news/messages_sv.po
|
||||
trans.tr_TR = apps/routerconsole/locale-news/messages_tr.po
|
||||
trans.uk_UA = apps/routerconsole/locale-news/messages_uk.po
|
||||
trans.zh_CN = apps/routerconsole/locale-news/messages_zh.po
|
||||
trans.zh_TW = apps/routerconsole/locale-news/messages_zh_TW.po
|
||||
|
||||
[I2P.countries]
|
||||
type = PO
|
||||
source_file = apps/routerconsole/locale-countries/messages_en.po
|
||||
source_lang = en
|
||||
trans.ca = apps/routerconsole/locale-countries/messages_ca.po
|
||||
trans.da = apps/routerconsole/locale-countries/messages_da.po
|
||||
trans.de = apps/routerconsole/locale-countries/messages_de.po
|
||||
trans.el = apps/routerconsole/locale-countries/messages_el.po
|
||||
trans.es = apps/routerconsole/locale-countries/messages_es.po
|
||||
trans.et_EE = apps/routerconsole/locale-countries/messages_et.po
|
||||
trans.fi = apps/routerconsole/locale-countries/messages_fi.po
|
||||
trans.fr = apps/routerconsole/locale-countries/messages_fr.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.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
|
||||
trans.pl = apps/routerconsole/locale-countries/messages_pl.po
|
||||
trans.pt = apps/routerconsole/locale-countries/messages_pt.po
|
||||
trans.pt_BR = apps/routerconsole/locale-countries/messages_pt_BR.po
|
||||
trans.ro = apps/routerconsole/locale-countries/messages_ro.po
|
||||
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.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
|
||||
|
||||
[I2P.i2psnark]
|
||||
source_file = apps/i2psnark/locale/messages_en.po
|
||||
@ -58,7 +155,10 @@ trans.nb = apps/i2psnark/locale/messages_nb.po
|
||||
trans.nl = apps/i2psnark/locale/messages_nl.po
|
||||
trans.pl = apps/i2psnark/locale/messages_pl.po
|
||||
trans.pt = apps/i2psnark/locale/messages_pt.po
|
||||
trans.pt_BR = apps/i2psnark/locale/messages_pt_bR.po
|
||||
trans.ro = apps/i2psnark/locale/messages_ro.po
|
||||
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.vi = apps/i2psnark/locale/messages_vi.po
|
||||
trans.zh_CN = apps/i2psnark/locale/messages_zh.po
|
||||
@ -75,11 +175,15 @@ trans.es = apps/susidns/locale/messages_es.po
|
||||
trans.fr = apps/susidns/locale/messages_fr.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.nl = apps/susidns/locale/messages_nl.po
|
||||
trans.pl = apps/susidns/locale/messages_pl.po
|
||||
trans.pt = apps/susidns/locale/messages_pt.po
|
||||
trans.pt_BR = apps/susidns/locale/messages_pt_BR.po
|
||||
trans.ro = apps/susidns/locale/messages_ro.po
|
||||
trans.ru_RU = apps/susidns/locale/messages_ru.po
|
||||
trans.sv_SE = apps/susidns/locale/messages_sv.po
|
||||
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
|
||||
@ -96,9 +200,13 @@ trans.es = apps/desktopgui/locale/messages_es.po
|
||||
trans.fr = apps/desktopgui/locale/messages_fr.po
|
||||
trans.hu = apps/desktopgui/locale/messages_hu.po
|
||||
trans.it = apps/desktopgui/locale/messages_it.po
|
||||
trans.ja = apps/desktopgui/locale/messages_ja.po
|
||||
trans.nl = apps/desktopgui/locale/messages_nl.po
|
||||
trans.pl = apps/desktopgui/locale/messages_pl.po
|
||||
trans.pt_BR = apps/desktopgui/locale/messages_pt_BR.po
|
||||
trans.ro = apps/desktopgui/locale/messages_ro.po
|
||||
trans.ru_RU = apps/desktopgui/locale/messages_ru.po
|
||||
trans.sk = apps/desktopgui/locale/messages_sk.po
|
||||
trans.sv_SE = apps/desktopgui/locale/messages_sv.po
|
||||
trans.uk_UA = apps/desktopgui/locale/messages_uk.po
|
||||
trans.tr_TR = apps/desktopgui/locale/messages_tr.po
|
||||
@ -109,16 +217,25 @@ trans.zh_CN = apps/desktopgui/locale/messages_zh.po
|
||||
source_file = apps/susimail/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.cs = apps/susimail/locale/messages_cs.po
|
||||
trans.da = apps/susimail/locale/messages_da.po
|
||||
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.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.mg = apps/susimail/locale/messages_mg.po
|
||||
trans.nl = apps/susimail/locale/messages_nl.po
|
||||
trans.ru_RU = apps/susimail/locale/messages_ru.po
|
||||
trans.sv_SE = apps/susimail/locale/messages_sv.po
|
||||
trans.pl = apps/susimail/locale/messages_pl.po
|
||||
trans.pt = apps/susimail/locale/messages_pt.po
|
||||
trans.pt_BR = apps/susimail/locale/messages_pt_BR.po
|
||||
trans.ro = apps/susimail/locale/messages_ro.po
|
||||
trans.ru_RU = apps/susimail/locale/messages_ru.po
|
||||
trans.sq = apps/susimail/locale/messages_sq.po
|
||||
trans.sv_SE = apps/susimail/locale/messages_sv.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
|
||||
@ -130,12 +247,21 @@ trans.cs = debian/po/cs.po
|
||||
trans.de = debian/po/de.po
|
||||
trans.el = debian/po/el.po
|
||||
trans.es = debian/po/es.po
|
||||
trans.fi = debian/po/fi.po
|
||||
trans.fr = debian/po/fr.po
|
||||
trans.id = debian/po/id.po
|
||||
trans.it = debian/po/it.po
|
||||
trans.hu = debian/po/hu.po
|
||||
trans.ja = debian/po/ja.po
|
||||
trans.ko = debian/po/ko.po
|
||||
trans.nl = debian/po/nl.po
|
||||
trans.pl = debian/po/pl.po
|
||||
trans.pt = debian/po/pt.po
|
||||
trans.pt_BR = debian/po/pt_BR.po
|
||||
trans.ro = debian/po/ro.po
|
||||
trans.ru_RU = debian/po/ru.po
|
||||
trans.sk = debian/po/sk.po
|
||||
trans.sq = debian/po/sq.po
|
||||
trans.sv_SE = debian/po/sv.po
|
||||
trans.uk_UA = debian/po/uk.po
|
||||
trans.tr_TR = debian/po/tr.po
|
||||
@ -144,14 +270,80 @@ trans.zh_CN = debian/po/zh.po
|
||||
[I2P.i2prouter-script]
|
||||
source_file = installer/resources/locale/po/messages_en.po
|
||||
source_lang = en
|
||||
;; currently fails check
|
||||
;;trans.ca = installer/resources/locale/po/messages_ca.po
|
||||
trans.de = installer/resources/locale/po/messages_de.po
|
||||
trans.es = installer/resources/locale/po/messages_es.po
|
||||
;; currently fails check
|
||||
;;trans.fi = installer/resources/locale/po/messages_fi.po
|
||||
trans.fr = installer/resources/locale/po/messages_fr.po
|
||||
trans.id = installer/resources/locale/po/messages_id.po
|
||||
trans.it = installer/resources/locale/po/messages_it.po
|
||||
trans.sv_SE = installer/resources/locale/po/messages_sv.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.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
|
||||
trans.pt_BR = installer/resources/locale/po/messages_pt_BR.po
|
||||
trans.ro = installer/resources/locale/po/messages_ro.po
|
||||
trans.ru_RU = installer/resources/locale/po/messages_ru.po
|
||||
trans.sk = installer/resources/locale/po/messages_sk.po
|
||||
trans.sv_SE = installer/resources/locale/po/messages_sv.po
|
||||
trans.tr_TR = installer/resources/locale/po/messages_tr.po
|
||||
;; currently fails check
|
||||
;;trans.uk_UA = installer/resources/locale/po/messages_uk.po
|
||||
trans.zh_CN = installer/resources/locale/po/messages_zh.po
|
||||
|
||||
[main]
|
||||
host = http://www.transifex.net
|
||||
[I2P.getopt]
|
||||
source_file = core/java/src/gnu/getopt/MessagesBundle.properties
|
||||
source_lang = en
|
||||
type = PROPERTIES
|
||||
trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties
|
||||
trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
|
||||
trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties
|
||||
trans.fi = core/java/src/gnu/getopt/MessagesBundle_fi.properties
|
||||
trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.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
|
||||
trans.it = core/java/src/gnu/getopt/MessagesBundle_it.properties
|
||||
trans.ja = core/java/src/gnu/getopt/MessagesBundle_ja.properties
|
||||
trans.ko = core/java/src/gnu/getopt/MessagesBundle_ko.properties
|
||||
trans.nl = core/java/src/gnu/getopt/MessagesBundle_nl.properties
|
||||
trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties
|
||||
trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties
|
||||
;; currently corrupt, non-UTF-8
|
||||
;;trans.pt = core/java/src/gnu/getopt/MessagesBundle_pt.properties
|
||||
;; currently corrupt, non-UTF-8
|
||||
;;trans.pt_BR = core/java/src/gnu/getopt/MessagesBundle_pt_BR.properties
|
||||
trans.ro = core/java/src/gnu/getopt/MessagesBundle_ro.properties
|
||||
trans.ru_RU = core/java/src/gnu/getopt/MessagesBundle_ru.properties
|
||||
trans.sk = core/java/src/gnu/getopt/MessagesBundle_sk.properties
|
||||
;; currently corrupt, non-UTF-8
|
||||
;;trans.sq = core/java/src/gnu/getopt/MessagesBundle_sq.properties
|
||||
trans.uk_UA = core/java/src/gnu/getopt/MessagesBundle_uk.properties
|
||||
trans.zh_CN = core/java/src/gnu/getopt/MessagesBundle_zh.properties
|
||||
|
||||
[I2P.streaming]
|
||||
source_file = apps/ministreaming/locale/messages_en.po
|
||||
source_lang = en
|
||||
trans.ca = apps/ministreaming/locale/messages_ca.po
|
||||
trans.de = apps/ministreaming/locale/messages_de.po
|
||||
trans.es = apps/ministreaming/locale/messages_es.po
|
||||
trans.fr = apps/ministreaming/locale/messages_fr.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/ministreaming/locale/messages_in.po
|
||||
trans.it = apps/ministreaming/locale/messages_it.po
|
||||
trans.nb = apps/ministreaming/locale/messages_nb.po
|
||||
trans.pl = apps/ministreaming/locale/messages_pl.po
|
||||
trans.ro = apps/ministreaming/locale/messages_ro.po
|
||||
trans.ru_RU = apps/ministreaming/locale/messages_ru.po
|
||||
trans.sv_SE = apps/ministreaming/locale/messages_sv.po
|
||||
trans.uk_UA = apps/ministreaming/locale/messages_uk.po
|
||||
trans.zh_CN = apps/ministreaming/locale/messages_zh.po
|
||||
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
|
@ -12,7 +12,7 @@ you may use:
|
||||
to configure the router.
|
||||
|
||||
If you're having trouble, swing by http://forum.i2p/, check the
|
||||
website at http://www.i2p2.de/, or get on irc://irc.freenode.net/#i2p
|
||||
website at https://geti2p.net/, or get on irc://irc.freenode.net/#i2p
|
||||
|
||||
I2P will create and store files and configuration data in the user directory
|
||||
~/.i2p/ on Linux and %APPDATA%\I2P\ on Windows. This directory is created
|
||||
@ -25,21 +25,25 @@ where there are comments labeled "PORTABLE". Do this before you
|
||||
run I2P for the first time.
|
||||
|
||||
To start I2P:
|
||||
(*nix): sh i2prouter start
|
||||
(*nix, BSD, Mac): sh i2prouter start
|
||||
(win*): I2P.exe
|
||||
(non-x86 platforms PPC, ARM, etc): sh runplain.sh
|
||||
(platforms without wrapper support): sh runplain.sh
|
||||
|
||||
To stop I2P (gracefully):
|
||||
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
||||
or (*nix, BSD, Mac) sh i2prouter graceful
|
||||
|
||||
To stop I2P immediately:
|
||||
sh i2prouter stop
|
||||
(*nix, BSD, Mac) sh i2prouter stop
|
||||
|
||||
To uninstall I2P:
|
||||
rm -rf $I2PInstallDir ~/.i2p
|
||||
|
||||
Supported JVMs:
|
||||
Windows: Latest available from http://java.com/download (1.5+ supported)
|
||||
Linux: Latest available from http://java.com/download (1.5+ supported)
|
||||
FreeBSD: 1.5-compatible (NIO required)
|
||||
Other operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
||||
All platforms: Java 1.7 or higher required
|
||||
Windows: OpenJDK or Oracle from http://java.com/download
|
||||
Linux: OpenJDK or Oracle from http://java.com/download
|
||||
FreeBSD: OpenJDK or Oracle from http://java.com/download
|
||||
Raspberry Pi: Oracle 8 Early Access https://jdk8.java.net/download.html
|
||||
PowerPC: IBM SDK 7 http://www.ibm.com/developerworks/java/jdk/linux/download.html
|
||||
Other operating systems and JVMs: See https://trac.i2p2.de/wiki/java or https://geti2p.net/download
|
||||
|
25
INSTALL.txt
25
INSTALL.txt
@ -1,11 +1,13 @@
|
||||
I2P source installation instructions
|
||||
|
||||
Prerequisites to build from source:
|
||||
Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
|
||||
Non-linux operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
||||
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/
|
||||
from the GNU gettext package http://www.gnu.org/software/gettext/
|
||||
Build environment must use a UTF-8 locale.
|
||||
|
||||
To build and install I2P from source, you must first build
|
||||
and package up the appropriate installer by running:
|
||||
@ -40,29 +42,30 @@ or on Windows, just double-click on i2pinstall.exe.
|
||||
Or move the i2pupdate.zip file into an existing installation directory and restart.
|
||||
|
||||
To start I2P:
|
||||
(*nix): sh i2prouter start
|
||||
(*nix, BSD, Mac): sh i2prouter start
|
||||
(win*): I2P.exe or i2prouter.bat
|
||||
(non-x86 platforms PPC, ARM, etc): sh runplain.sh
|
||||
(platforms without wrapper support): sh runplain.sh
|
||||
|
||||
To install I2P as a system service:
|
||||
(*nix) sh i2prouter install
|
||||
(*nix, BSD, Mac) sh i2prouter install
|
||||
(win*) install_i2p_service_winnt.bat
|
||||
|
||||
To uninstall I2P as a system service:
|
||||
(*nix) sh i2prouter remove
|
||||
(*nix, BSD, Mac) sh i2prouter remove
|
||||
(win*) uninstall_i2p-service_winnt.bat
|
||||
|
||||
To stop I2P (gracefully):
|
||||
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
||||
or (*nix, BSD, Mac) sh i2prouter graceful
|
||||
|
||||
To stop I2P immediately:
|
||||
sh i2prouter stop
|
||||
(*nix, BSD, Mac) sh i2prouter stop
|
||||
|
||||
To uninstall I2P:
|
||||
rm -rf $I2PInstallDir ~/.i2p
|
||||
|
||||
Supported JVMs:
|
||||
Windows: Latest available from http://java.com/download (1.5+ supported)
|
||||
Linux: Latest available from http://java.com/download (1.5+ supported)
|
||||
FreeBSD: 1.5-compatible (NIO required)
|
||||
Windows: Latest available from http://java.com/download (1.7+ supported)
|
||||
Linux: Latest available from http://java.com/download (1.7+ supported)
|
||||
FreeBSD: 1.7-compatible (NIO required)
|
||||
Other operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
||||
|
23
LICENSE.txt
23
LICENSE.txt
@ -36,7 +36,7 @@ Public domain except as listed below:
|
||||
Copyright (c) 2003, TheCrypto
|
||||
See licenses/LICENSE-ElGamalDSA.txt
|
||||
|
||||
SHA256 and HMAC-SHA256:
|
||||
SHA256 and HMAC:
|
||||
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
|
||||
See licenses/LICENSE-SHA256.txt
|
||||
|
||||
@ -76,13 +76,22 @@ Public domain except as listed below:
|
||||
Copyright 2012 Hiroshi Nakamura <nahi@ruby-lang.org>
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
|
||||
Getopt:
|
||||
Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
HostnameVerifier:
|
||||
From Apache HttpClient 4.4.1 and HttpCore 4.4.1
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
|
||||
|
||||
Router (router.jar):
|
||||
Public domain except as listed below:
|
||||
UPnP.java:
|
||||
From freenet
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
UPnP subsystem (CyberLink) 2.1:
|
||||
UPnP subsystem (CyberLink) 3.0:
|
||||
Copyright (C) 2003-2010 Satoshi Konno
|
||||
See licenses/LICENSE-UPnP.txt
|
||||
|
||||
@ -132,7 +141,7 @@ Installer:
|
||||
|
||||
|
||||
|
||||
Java Service Wrapper Community Edition 32-bit 3.5.19:
|
||||
Java Service Wrapper Community Edition 32-bit 3.5.25:
|
||||
Copyright (C) 1999-2011 Tanuki Software, Ltd. All Rights Reserved.
|
||||
See licenses/LICENSE-Wrapper.txt
|
||||
|
||||
@ -177,7 +186,7 @@ Applications:
|
||||
By welterde.
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
Jetty 7.6.11.v20130520:
|
||||
Jetty 8.1.17.v20150415:
|
||||
See licenses/ABOUT-Jetty.html
|
||||
See licenses/NOTICE-Jetty.html
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
@ -207,7 +216,7 @@ Applications:
|
||||
FatCow icons: See licenses/LICENSE-FatCowIcons.txt
|
||||
|
||||
GeoIP Data:
|
||||
Copyright (c) 2008 MaxMind, Inc. All Rights Reserved.
|
||||
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/
|
||||
See licenses/LICENSE-GeoIP.txt
|
||||
|
||||
Router Console and I2PSnark themes:
|
||||
@ -243,8 +252,8 @@ Applications:
|
||||
Bundles systray4j-2.4.1:
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
Tomcat 6.0.37:
|
||||
Copyright 1999-2013 The Apache Software Foundation
|
||||
Tomcat 6.0.44:
|
||||
Copyright 1999-2015 The Apache Software Foundation
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Tomcat.txt
|
||||
|
||||
|
28
README.txt
28
README.txt
@ -1,9 +1,11 @@
|
||||
Prerequisites to build from source:
|
||||
Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
|
||||
Non-linux operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
||||
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:
|
||||
@ -15,25 +17,35 @@ To build:
|
||||
ant installer-osx
|
||||
|
||||
Run 'ant' with no arguments to see other build options.
|
||||
See INSTALL.txt or http://www.i2p2.de/download.html for installation instructions.
|
||||
See INSTALL.txt or https://geti2p.net/download for installation instructions.
|
||||
|
||||
Documentation:
|
||||
http://www.i2p2.de/how
|
||||
API: run 'ant javadoc' then start at build/javadoc/index.html
|
||||
https://geti2p.net/how
|
||||
API: http://docs.i2p-projekt.de/javadoc/
|
||||
or run 'ant javadoc' then start at build/javadoc/index.html
|
||||
|
||||
Latest release:
|
||||
http://www.i2p2.de/download.html
|
||||
https://geti2p.net/download
|
||||
|
||||
To get development branch from source control:
|
||||
http://www.i2p2.de/newdevelopers.html
|
||||
https://geti2p.net/newdevelopers
|
||||
|
||||
FAQ:
|
||||
http://www.i2p2.de/faq.html
|
||||
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
|
||||
|
||||
|
@ -1,30 +1,70 @@
|
||||
ou will need atleast monotone > = 0.41 to get the most recent build source
|
||||
and connect it to an already running i2p router.
|
||||
Getting the sources
|
||||
===================
|
||||
|
||||
OR:
|
||||
Monotone
|
||||
--------
|
||||
|
||||
You may download the actual "stable" source from
|
||||
http://code.google.com/p/i2p/downloads/list
|
||||
The bleeding-edge source code is available both within and outside of I2P. The
|
||||
I2P project uses Monotone to maintain the codebase.
|
||||
|
||||
You will need to follwing tools to build the i2p and i2p-base packages:
|
||||
Information on retrieving the source with monotone is available within I2P at
|
||||
http://i2p-projekt.i2p/monotone and from the internet at https://geti2p.net/monotone.
|
||||
|
||||
bash >= 3.1.017
|
||||
requiredbuilder >= 0.16.3 ( http://www.stabellini.net/requiredbuilder.html )
|
||||
jre >= 6u11
|
||||
jdk >= 6u11
|
||||
apache-ant >= 1.7.1
|
||||
perl >= 5.10.0
|
||||
python >= 2.5.2
|
||||
Monotone 1.0 Slackbuilds are available at http://slackbuilds.org/.
|
||||
|
||||
Reccomended:
|
||||
monotone >= 0.41 ( http://pkgs.dr.ea.ms )
|
||||
Git
|
||||
---
|
||||
|
||||
See also:
|
||||
Git is also an option to retrieve the I2P source code. That said, the I2P
|
||||
Monotone servers are *the* authoritative source.
|
||||
|
||||
i2p/readme.txt
|
||||
Public Git repositories hosting the I2P source and managed by I2P project team members include
|
||||
|
||||
AND
|
||||
- https://github.com/i2p/i2p.i2p
|
||||
- http://git.repo.i2p/w/i2p.i2p.git (mirrored from Github)
|
||||
- http://sourceforge.net/p/i2p/code/
|
||||
|
||||
i2p-base/readme.txt
|
||||
|
||||
for information and handy tips.
|
||||
Tarball
|
||||
-------
|
||||
|
||||
The latest stable release is always available from the I2P homepage at
|
||||
https://geti2p.net/get/.
|
||||
|
||||
|
||||
This SlackBuild
|
||||
===============
|
||||
|
||||
Requirements
|
||||
-------------
|
||||
|
||||
The following are needed to build the i2p package:
|
||||
|
||||
* jre >= 6
|
||||
* jdk >= 6
|
||||
* gettext
|
||||
* apache-ant >= 1.7.1
|
||||
|
||||
If you don't care about bundling the translations, the gettext requirement can
|
||||
be avoided by adding -Drequire.gettext=false to the ant lines in
|
||||
i2p/i2p.SlackBuild
|
||||
|
||||
A JRE >= v6 is the only requirement to run I2P.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
As the root user, run either $I2PSRC/Slackware/i2p/i2p.SlackBuild or `ant slackpkg` to create a package
|
||||
in $I2PSRC/Slackware/i2p which can be installed using the Slackware packaging tools.
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
Please also take a look at
|
||||
|
||||
* i2p/README
|
||||
* eepget(1)
|
||||
* i2prouter(1)
|
||||
* http://i2p-projekt.i2p / https://geti2p.net
|
||||
|
||||
for additional information and tips.
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project basedir="." default="slackpkg">
|
||||
<target name="slackpkg">
|
||||
<echo message="Building Slackware package." />
|
||||
<exec executable="./i2p-base.SlackBuild">
|
||||
</exec>
|
||||
</target>
|
||||
</project>
|
@ -1,157 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
# Now in the future we only need to look for '#I2P' and '#/I2P'
|
||||
# for modifications to rc.local and rc.local_shutdown.
|
||||
# I was a moron for not doing it this way in the first place :-) -- Sponge
|
||||
#
|
||||
#
|
||||
|
||||
touch /etc/rc.d/rc.local
|
||||
touch /etc/rc.d/rc.local_shutdown
|
||||
|
||||
echo
|
||||
echo -n "Check 1: /etc/rc.d/rc.local "
|
||||
I2PRCA=`grep -c /etc/rc.d/rc.local -e '/etc/rc.d/rc.i2p'`
|
||||
|
||||
if [ $I2PRCA -eq 0 ] ; then
|
||||
echo '#I2P' >> /etc/rc.d/rc.local
|
||||
echo '( cd /tmp ; rm -Rf i2p-*.tmp )' >> /etc/rc.d/rc.local
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local
|
||||
echo " sh /etc/rc.d/rc.i2p start" >> /etc/rc.d/rc.local
|
||||
echo "fi" >> /etc/rc.d/rc.local
|
||||
echo '#/I2P' >> /etc/rc.d/rc.local
|
||||
echo "modified."
|
||||
else
|
||||
echo -n "looks OK so far,"
|
||||
# Fix old installs, or where people have modified.
|
||||
|
||||
echo -n " Check 1A: "
|
||||
I2PRCC=`grep -c /etc/rc.d/rc.local -e 'i2p-\*\.tmp'`
|
||||
|
||||
if [ $I2PRCC -eq 0 ] ; then
|
||||
DATA=$(cat /etc/rc.d/rc.local | sed -re 's/if \[ -x \/etc\/rc\.d\/rc\.i2p \] ; then/#I2P\n\( cd \/tmp ; rm -Rf i2p-*.tmp \)\nif \[ -x \/etc\/rc.d\/rc.i2p \] ; then/')
|
||||
echo "${DATA}" > /etc/rc.d/rc.local
|
||||
echo -n "additional modifications applied,"
|
||||
else
|
||||
echo -n "looks OK so far,"
|
||||
fi
|
||||
|
||||
echo -n " Check 1B: "
|
||||
I2PRCE=`grep -c /etc/rc.d/rc.local -e 'i2p-\*\.tmp'`
|
||||
if [ $I2PRCE -eq 0 ] ; then
|
||||
DATATOP=$(cat /etc/rc.d/rc.local | sed -n '0,/i2p-\*\.tmp/p' | sed '$d' )
|
||||
DATABOT=$(cat /etc/rc.d/rc.local | sed -n '/i2p-\*\.tmp/,$p' | sed -n '/^fi/,$p' | sed "1d")
|
||||
echo "${DATATOP}" > /etc/rc.d/rc.local
|
||||
echo '#I2P' >> /etc/rc.d/rc.local
|
||||
echo '( cd /tmp ; rm -Rf i2p-*.tmp )' >> /etc/rc.d/rc.local
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local
|
||||
echo " sh /etc/rc.d/rc.i2p start" >> /etc/rc.d/rc.local
|
||||
echo "fi" >> /etc/rc.d/rc.local
|
||||
echo '#/I2P' >> /etc/rc.d/rc.local
|
||||
echo "${DATABOT}" >> /etc/rc.d/rc.local
|
||||
|
||||
echo -n "additional modifications applied,"
|
||||
else
|
||||
echo -n "looks ok so far,"
|
||||
fi
|
||||
echo -n " Check 1C: "
|
||||
I2PRCF=`grep -c /etc/rc.d/rc.local -e '#/I2P'`
|
||||
if [ $I2PRCF -eq 0 ] ; then
|
||||
DATATOP=$(cat /etc/rc.d/rc.local | sed -n '0,/^#I2P/p' | sed '$d' )
|
||||
DATABOT=$(cat /etc/rc.d/rc.local | sed -n '/^#I2P/,$p' | sed -n '/^fi/,$p' | sed "1d")
|
||||
echo "${DATATOP}" > /etc/rc.d/rc.local
|
||||
echo '#I2P' >> /etc/rc.d/rc.local
|
||||
echo '( cd /tmp ; rm -Rf i2p-*.tmp )' >> /etc/rc.d/rc.local
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local
|
||||
echo " sh /etc/rc.d/rc.i2p start" >> /etc/rc.d/rc.local
|
||||
echo "fi" >> /etc/rc.d/rc.local
|
||||
echo '#/I2P' >> /etc/rc.d/rc.local
|
||||
echo "${DATABOT}" >> /etc/rc.d/rc.local
|
||||
|
||||
echo -n "additional modifications applied,"
|
||||
else
|
||||
echo -n "looks ok so far,"
|
||||
fi
|
||||
echo " Done."
|
||||
fi
|
||||
|
||||
echo -n "Check 2: /etc/rc.d/rc.local_shutdown "
|
||||
I2PRCB=`grep -c /etc/rc.d/rc.local_shutdown -e '/etc/rc.d/rc.i2p'`
|
||||
if [ $I2PRCB -eq 0 ] ; then
|
||||
echo "#I2P" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local_shutdown
|
||||
echo " sh /etc/rc.d/rc.i2p stop" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "fi" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "#/I2P" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "modified."
|
||||
else
|
||||
echo -n "looks OK so far,"
|
||||
# Fix old installs
|
||||
|
||||
echo -n " Check 1A: "
|
||||
I2PRCG=`grep -c /etc/rc.d/rc.local_shutdown -e '#I2P'`
|
||||
if [ $I2PRCG -eq 0 ] ; then
|
||||
DATATOP=$(cat /etc/rc.d/rc.local_shutdown | sed -n '0,/^if \[ -x \/etc\/rc\.d\/rc\.i2p \] ; then/p' | sed '$d' )
|
||||
DATABOT=$(cat /etc/rc.d/rc.local_shutdown | sed -n '/^if \[ -x \/etc\/rc\.d\/rc\.i2p \] ; then/,$p' | sed -n '/^fi/,$p' | sed "1d")
|
||||
echo "${DATATOP}" > /etc/rc.d/rc.local_shutdown
|
||||
echo '#I2P' >> /etc/rc.d/rc.local_shutdown
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local_shutdown
|
||||
echo " sh /etc/rc.d/rc.i2p stop" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "fi" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "#/I2P" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "${DATABOT}" >> /etc/rc.d/rc.local_shutdown
|
||||
echo -n "additional modifications applied,"
|
||||
else
|
||||
echo -n "looks OK so far,"
|
||||
fi
|
||||
echo -n " Check 1B: "
|
||||
I2PRCH=`grep -c /etc/rc.d/rc.local_shutdown -e '#/I2P'`
|
||||
if [ $I2PRCH -eq 0 ] ; then
|
||||
DATATOP=$(cat /etc/rc.d/rc.local_shutdown | sed -n '0,/^#I2P/p' | sed '$d' )
|
||||
DATABOT=$(cat /etc/rc.d/rc.local_shutdown | sed -n '/^#I2P/,$p' | sed -n '/^fi/,$p' | sed "1d")
|
||||
echo "${DATATOP}" > /etc/rc.d/rc.local_shutdown
|
||||
echo '#I2P' >> /etc/rc.d/rc.local_shutdown
|
||||
echo "if [ -x /etc/rc.d/rc.i2p ] ; then" >> /etc/rc.d/rc.local_shutdown
|
||||
echo " sh /etc/rc.d/rc.i2p stop" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "fi" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "#/I2P" >> /etc/rc.d/rc.local_shutdown
|
||||
echo "${DATABOT}" >> /etc/rc.d/rc.local_shutdown
|
||||
echo -n "additional modifications applied,"
|
||||
else
|
||||
echo -n "looks OK so far,"
|
||||
fi
|
||||
echo " Done."
|
||||
fi
|
||||
|
||||
if [ -f /etc/rc.d/rc.i2p ] ; then
|
||||
if [ -x /etc/rc.d/rc.i2p ] ; then
|
||||
chmod +x /etc/rc.d/rc.i2p.new
|
||||
fi
|
||||
# Hopefully get admin's attention.
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -e "\007" ; sleep 0.3
|
||||
echo "It apears that you already have /etc/rc.d/rc.i2p"
|
||||
echo "You should replace it with /etc/rc.d/rc.i2p.new as soon as possible"
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -ne "\007" ; sleep 0.3
|
||||
echo -e "\007" ; sleep 0.3
|
||||
else
|
||||
mv /etc/rc.d/rc.i2p.new /etc/rc.d/rc.i2p
|
||||
echo
|
||||
echo "Installation finished. The i2p start/stop script has been"
|
||||
echo "installed in /etc/rc.d . You should chmod +x"
|
||||
echo '/etc/rc.d/rc.i2p to start it on boot.'
|
||||
echo
|
||||
fi
|
||||
|
||||
exit
|
@ -1,57 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Heavily based on the Slackware 12.2 SlackBuild
|
||||
# Slackware build script for I2P
|
||||
#
|
||||
# PLEASE READ THIS:
|
||||
# How to start I2P:
|
||||
# After installpkg command, doinst.sh will execute a post-installation script
|
||||
# needed by I2P. After that you have to chmod +x /etc/rc.d/rc.i2p and start
|
||||
# I2P service with /etc/rc.d/rc.i2p start.
|
||||
#
|
||||
# Now tell your browser to user this proxy: localhost on port 4444 and open
|
||||
# this page: http://localhost:7657/index.jsp
|
||||
#
|
||||
# Here you can configure I2P, watch network status and navigate anonimously.
|
||||
# It's suggested to subscribe to various dns host, like i2host.i2p
|
||||
# For any additional information, visit i2host.i2p and forum.i2p
|
||||
#
|
||||
|
||||
CWD=$(pwd)
|
||||
TMP=/tmp
|
||||
PKG=/$TMP/package-base-i2p
|
||||
NAME=i2p-base
|
||||
VERSION=0.0.4
|
||||
BUILD=1sponge
|
||||
ARCH=noarch
|
||||
INSTALL_DIR=opt
|
||||
|
||||
# Less than slackware 13?
|
||||
SLKPLT=$(cat /etc/slackware-version | sed -re "s/(Slackware )([0-9]*)(.*)/\2/")
|
||||
if [ $SLKPLT -lt 13 ] ; then
|
||||
EXT=tgz
|
||||
else
|
||||
EXT=txz
|
||||
fi
|
||||
|
||||
rm -rf $PKG
|
||||
mkdir -p $PKG
|
||||
cd $PKG
|
||||
chown -R root:root .
|
||||
|
||||
mkdir -p $PKG/etc/rc.d
|
||||
mkdir -p $PKG/install
|
||||
sed "s|directory|/$INSTALL_DIR/i2p/i2prouter|g" "$CWD/rc.i2p_def" > $PKG/etc/rc.d/rc.i2p.new
|
||||
chmod 644 $PKG/etc/rc.d/rc.i2p.new
|
||||
cat "$CWD/doinst.sh" > $PKG/install/doinst.sh
|
||||
cat "$CWD/slack-desc" > $PKG/install/slack-desc
|
||||
|
||||
cd $PKG
|
||||
#
|
||||
# Not really that important to exec this
|
||||
# as there aren't any deps we don't know.
|
||||
#
|
||||
# requiredbuilder -v -y -s $CWD $PKG
|
||||
#
|
||||
cat "$CWD/slack-required" > $PKG/install/slack-required
|
||||
makepkg -l y -c n $CWD/${NAME}-$VERSION-$ARCH-$BUILD.$EXT
|
@ -1,68 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Start/stop i2p service.
|
||||
|
||||
i2p_start() {
|
||||
# Check if router is up first!
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory status )'" > /dev/null
|
||||
if [ $? -eq 0 ] ; then {
|
||||
# I2p is already running, so tell the user.
|
||||
echo "I2P is already running..."
|
||||
i2p_status
|
||||
}
|
||||
else
|
||||
{
|
||||
# Just in-case there are leftover junk in /tmp...
|
||||
rm -Rf `grep /tmp/hsperfdata_root/* -le i2p` /tmp/i2p-*.tmp /tmp/router.ping
|
||||
# Now that all junk is cleaned up, start.
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory start )'"
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
i2p_stop() {
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory stop )'"
|
||||
rm -Rf `grep /tmp/hsperfdata_root/* -le i2p` /tmp/i2p-*.tmp /tmp/router.ping
|
||||
}
|
||||
|
||||
i2p_restart() {
|
||||
# We want a FULL cycle here, not the wrappers idea of this!
|
||||
i2p_stop
|
||||
i2p_start
|
||||
}
|
||||
|
||||
i2p_status() {
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory status )'"
|
||||
}
|
||||
|
||||
i2p_console() {
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory console )'"
|
||||
}
|
||||
|
||||
i2p_dump() {
|
||||
/bin/su - -c "/bin/bash -l -c '( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\" ; directory dump )'"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
i2p_start
|
||||
;;
|
||||
'stop')
|
||||
i2p_stop
|
||||
;;
|
||||
'restart')
|
||||
i2p_restart
|
||||
;;
|
||||
'status')
|
||||
i2p_status
|
||||
;;
|
||||
'console')
|
||||
i2p_console
|
||||
;;
|
||||
'dump')
|
||||
i2p_dump
|
||||
;;
|
||||
*)
|
||||
echo "usage $0 start|stop|restart|status|console|dump"
|
||||
;;
|
||||
esac
|
||||
|
@ -1,10 +0,0 @@
|
||||
An rc file called rc.i2p has been placed into the /etc/rc.d directory.
|
||||
If you want to change installation dir, change the variable INSTALL_DIR
|
||||
on base-i2p.SlackBuild and rebuild the package. You also will need to do the
|
||||
same for the i2p package.
|
||||
|
||||
The install script will insert everything needed into /etc/rc.d/rc.local and
|
||||
into /etc/rc.d/rc.local_shutdown automatically.
|
||||
|
||||
If you want to start I2P at boot you have to chmod +x /etc/rc.d/rc.i2p
|
||||
|
@ -1,19 +0,0 @@
|
||||
# HOW TO EDIT THIS FILE:
|
||||
# The "handy ruler" below makes it easier to edit a package description. Line
|
||||
# up the first '|' above the ':' following the base package name, and the '|' on
|
||||
# the right side marks the last column you can put a character in. You must make
|
||||
# exactly 11 lines for the formatting to be correct. It's also customary to
|
||||
# leave one space after the ':'.
|
||||
|
||||
|-----handy-ruler------------------------------------------------------|
|
||||
base-i2p: base-i2p (I2P anonymizing network base config files)
|
||||
base-i2p:
|
||||
base-i2p: I2P is an anonymizing network, offering a simple layer that
|
||||
base-i2p: identity-sensitive applications can use to securely communicate. All
|
||||
base-i2p: data is wrapped with several layers of encryption, and the network is
|
||||
base-i2p: both distributed and dynamic, with no trusted parties.
|
||||
base-i2p: Many applications are available that interface with I2P, including
|
||||
base-i2p: mail, peer-peer file sharing, IRC chat, and others.
|
||||
base-i2p:
|
||||
base-i2p: This package provides the startup files.
|
||||
base-i2p:
|
@ -1 +0,0 @@
|
||||
bash >= 3.1.017
|
89
Slackware/i2p/README
Normal file
89
Slackware/i2p/README
Normal file
@ -0,0 +1,89 @@
|
||||
The I2P package will be installed to /opt/i2p.
|
||||
|
||||
To install to another location, set the variable INSTALL_DIR in i2p.SlackBuild
|
||||
and rebuild the package.
|
||||
|
||||
|
||||
Installing and Upgrading:
|
||||
=========================
|
||||
|
||||
I2P has an auto-update function but generally speaking packages are managed by
|
||||
packaging systems. Changing a package's files outside of the package system can
|
||||
cause problems. To upgrade when there's a new I2P release, retrieve the new
|
||||
source, re-run the SlackBuild, then use upgradepkg to update.
|
||||
|
||||
To ignore all this and upgrade "in-network", simply change the permissions of the installation
|
||||
directory (/opt/i2p by default). Something like the following would suffice:
|
||||
|
||||
chown -R USERNAME /opt/i2p
|
||||
|
||||
|
||||
Starting and using I2P
|
||||
======================
|
||||
|
||||
Using the initscript
|
||||
--------------------
|
||||
|
||||
To start I2P at boot, set the executable bit on /etc/rc.d/rc.i2p, add this
|
||||
script to rc.local*, and set the variable "RUN_AS_USER" in /etc/rc.d/rc.i2p.
|
||||
|
||||
Optionally, create a new user/group with limited rights to run I2P.
|
||||
|
||||
Something like the following would work to start I2P at system boot, running under the
|
||||
"i2p" account:
|
||||
|
||||
echo '[ -x /etc/rc.d/rc.i2p ] && /etc/rc.d/rc.i2p start' >> /etc/rc.d/rc.local
|
||||
echo '[ -x /etc/rc.d/rc.i2p ] && /etc/rc.d/rc.i2p stop' >> /etc/.rc.d/rc.local_shutdown
|
||||
sed -i .bak 's/^.*\(RUN_AS_USER\)=.*/\1=i2p/' /etc/rc.d/rc.i2p
|
||||
chmod 755 /etc/rc.d/rc.i2p
|
||||
|
||||
Unless running as a user named "i2psvc", I2P's config directory defaults to
|
||||
$HOME/.i2p. In the case of the "i2psvc" user, the default config directory is
|
||||
/var/lib/i2p/i2p-config.
|
||||
|
||||
It should not need to be said that using the "root" account is not recommended.
|
||||
|
||||
When running using the initscript, I2P will write its logs to /var/log/i2p.
|
||||
|
||||
Starting I2P "on-demand"
|
||||
------------------------
|
||||
|
||||
As with a normal installation, I2P can be started with "i2prouter start". The
|
||||
i2prouter and eepget scripts hve been installed to /usr/bin so they'll be
|
||||
accessible in the default system PATH.
|
||||
|
||||
When running using the i2prouter script, I2P will write its logs to $HOME/.i2p.
|
||||
|
||||
|
||||
Configuring your browser
|
||||
------------------------
|
||||
|
||||
In order to access eepSites (I2P-internal web sites) your web browser needs to
|
||||
be configured. Set the HTTP Proxy to 127.0.0.1 and port 4444. For more information, see
|
||||
https://geti2p.net/en/about/browser-config
|
||||
|
||||
The I2P router console is reachable at http://127.0.0.1:7657.
|
||||
|
||||
|
||||
Addressbook subscriptions
|
||||
-------------------------
|
||||
|
||||
Please see the FAQs at http://i2p-projekt.i2p/faq or https://geti2p.net/faq for information about
|
||||
the various addressbook services.
|
||||
|
||||
|
||||
Chatting on IRC
|
||||
---------------
|
||||
|
||||
I2P comes preconfigured with a tunnel pointing to the I2P-only IRC network,
|
||||
Irc2P. Signing on is easy, just connect to 127.0.0.1 on port 6668. Do not
|
||||
configure a proxy in your IRC client.
|
||||
|
||||
|
||||
Additional information
|
||||
======================
|
||||
|
||||
Within I2P: http://i2p-projekt.i2p/, http://forum.i2p/, http://zzz.i2p/, http://trac.i2p2.i2p/
|
||||
On the Internet: https://geti2p.net/, https://trac.i2p2.de
|
||||
Manpages: i2prouter(1), eepget(1)
|
||||
|
@ -2,7 +2,7 @@
|
||||
<project basedir="." default="slackpkg">
|
||||
<target name="slackpkg">
|
||||
<echo message="Building Slackware package." />
|
||||
<exec executable="./i2p.SlackBuild">
|
||||
</exec>
|
||||
<chmod file="./i2p.Slackbuild" perm="755" />
|
||||
<exec executable="./i2p.SlackBuild" failifexecutionfails="true" />
|
||||
</target>
|
||||
</project>
|
||||
|
@ -1,72 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Abort on error or unset variables
|
||||
set -e
|
||||
set -u
|
||||
|
||||
# This is changed by i2p.SlackBuild
|
||||
INST_DIR=directory
|
||||
PKGNAME="%pkg"
|
||||
|
||||
( cd install
|
||||
config() {
|
||||
NEW="$1"
|
||||
OLD="$(dirname $NEW)/$(basename $NEW .new)"
|
||||
if [ ! -r $NEW ]; then
|
||||
# If we get here there's a flaw in the packaging. We'll just return so that
|
||||
# we don't emit a spurious error for the user. (It's not the user's problem).
|
||||
return
|
||||
fi
|
||||
|
||||
echo
|
||||
for i in *.config ; {
|
||||
if [ -f $INST_DIR/$i ] ; then
|
||||
echo "Please check ${INST_DIR}${i}, as there is a new version."
|
||||
cp $i $INST_DIR/$i.new
|
||||
else
|
||||
cp $i $INST_DIR/$i
|
||||
fi
|
||||
# If this file doesn't exist yet, drop the .new extension.
|
||||
if [ ! -r $OLD ]; then
|
||||
mv $NEW $OLD
|
||||
return
|
||||
elif [ "$(md5sum $OLD | cut -d' ' -f1)" = "$(md5sum $NEW | cut -d' ' -f1)" ]; then
|
||||
# If there are no differences in the files, remove the file with the .new extension.
|
||||
rm $NEW
|
||||
return
|
||||
fi
|
||||
# Alert the admin if they differ, but let's not be terribly obnoxious about it.
|
||||
echo "WARNING: The files $OLD and $NEW differ." >&2
|
||||
}
|
||||
|
||||
)
|
||||
# Unlike previous versions of the package, we install i2prouter and eepget to /usr/bin
|
||||
# to make them available within the system PATH.
|
||||
|
||||
( cd $INST_DIR
|
||||
if [ -f blocklist.txt ] ; then
|
||||
echo "Please check ${INST_DIR}blocklist.txt, as there is a new version."
|
||||
else
|
||||
mv blocklist.txt.new blocklist.txt
|
||||
fi
|
||||
)
|
||||
# Users might still want to /opt/i2p/i2prouter or /opt/i2p/eepget so we'll create symlinks
|
||||
# in the installation directory.
|
||||
ln -sf /usr/bin/eepget $INST_DIR
|
||||
ln -sf /usr/bin/i2prouter $INST_DIR
|
||||
(cd /usr/doc/$PKGNAME; ln -sf $INST_DIR/history.txt changelog)
|
||||
|
||||
( cd $INST_DIR/eepsite
|
||||
if [ -f jetty.xml ] ; then
|
||||
echo "Please check ${INST_DIR}/eepsite, as there are new files."
|
||||
else
|
||||
find $PKG/$INSTALL_DIR/i2p -name "*.xml.new" -exec sh -c 'mv "$0" "${0/.new}"' {} \;
|
||||
fi
|
||||
)
|
||||
|
||||
( cd $INST_DIR/eepsite/docroot
|
||||
if [ -f index.html ] ; then
|
||||
rm index.html.new
|
||||
else
|
||||
mv index.html.new index.html
|
||||
fi
|
||||
if [ -f favicon.ico ] ; then
|
||||
rm favicon.ico.new
|
||||
else
|
||||
mv favicon.ico.new favicon.ico
|
||||
fi
|
||||
)
|
||||
|
||||
echo
|
||||
echo "FINISHING I2P INSTALLATION. PLEASE WAIT."
|
||||
|
||||
cd $INST_DIR
|
||||
|
||||
|
||||
|
||||
OS_ARCH=`uname -m`
|
||||
X86_64=`echo "$OS_ARCH" | grep x86_64`
|
||||
if [ "X$X86_64" = "X" ]; then
|
||||
wrapperpath="./lib/wrapper/linux"
|
||||
if $(uname -m | grep -q '64'); then
|
||||
(cd $INST_DIR; ln -sf i2psvc-linux-x86-64 i2psvc)
|
||||
else
|
||||
wrapperpath="./lib/wrapper/linux64"
|
||||
(cd $INST_DIR; ln -sf i2psvc-linux-x86-32 i2psvc)
|
||||
fi
|
||||
cp $wrapperpath/libwrapper.so ./lib/
|
||||
cp $wrapperpath/wrapper.jar ./lib/
|
||||
cp $wrapperpath/i2psvc .
|
||||
rm -rf ./lib/wrapper
|
||||
chmod 744 ./i2psvc
|
||||
|
||||
echo
|
||||
echo "Installation finished."
|
||||
echo
|
||||
config /etc/rc.d/rc.i2p.new
|
||||
config $INST_DIR/wrapper.config.new
|
||||
|
||||
exit
|
||||
if [ -e /var/log/packages/i2p-base* ]; then
|
||||
echo "Warning: This package supercedes 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
|
||||
echo "for correctness" >&2
|
||||
fi
|
||||
|
||||
# Remove extraneous 'sh' from sponge's set-up
|
||||
sed -i 's|sh /etc/rc\.d/rc\.i2p|/etc/rc.d/rc.i2p|g' /etc/rc.d/rc.local*
|
||||
|
@ -3,135 +3,124 @@
|
||||
# Heavily based on the Slackware 12.2 SlackBuild
|
||||
# Slackware build script for I2P
|
||||
#
|
||||
# PLEASE READ THIS:
|
||||
# Probably you will never have to update I2P packages with upgradepkg,
|
||||
# just because I2P has an auto-update function.
|
||||
# Really you should not ever use any "upgrade" method.
|
||||
#
|
||||
# The correct way to upgrade is to:
|
||||
# 1: install the upgrade
|
||||
# 2: remove the old package
|
||||
#
|
||||
# It is a terrible shame that upgradepkg doesn't do this, infact,
|
||||
# it would actually be the correct way for *any* package!
|
||||
# Packages are generally prohibited from being updated outside
|
||||
# of the package manager; this I2P SlackBuild is no different.
|
||||
#
|
||||
# If you'd like to use the I2P "in-network" updates anyway, you'll need to
|
||||
# grant the user that I2P will run as write permission to the installation directory
|
||||
# (/opt/i2p by default).
|
||||
#
|
||||
# For safety's sake, a user's I2P config files will *never* be overwritten by any upgrade method.
|
||||
# In the future this SlackBuild may alert when a default config file is updated.
|
||||
##
|
||||
|
||||
BUILD=1sponge
|
||||
# Make sure makepkg and friends can be found
|
||||
PATH=$PATH:/sbin
|
||||
|
||||
# abort on error and unset variables (same as set -e and set -u, respectively)
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
||||
if [ $(id -ur) -ne 0 ]; then
|
||||
echo "ERROR: SlackBuilds require root access." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILD=1kytv
|
||||
# INSTALL_DIR is referenced from /, don't prefix it with a '/'
|
||||
INSTALL_DIR=opt
|
||||
NAME=i2p
|
||||
ARCH=noarch
|
||||
|
||||
# Less than slackware 13?
|
||||
SLKPLT=$(cat /etc/slackware-version | sed -re "s/(Slackware )([0-9]*)(.*)/\2/")
|
||||
if [ $SLKPLT -lt 13 ] ; then
|
||||
EXT=tgz
|
||||
else
|
||||
EXT=txz
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# This mess is here due to the totally moronic way i2p does versioning.
|
||||
# We correct it here.
|
||||
#
|
||||
ROUTER=$(echo -ne "_")$(cat ../../router/java/src/net/i2p/router/RouterVersion.java | grep -e "public final static long BUILD" | cut -f2 -d"=" | cut -f1 -d";" | sed -re "s/ //g")
|
||||
if [ "$ROUTER" == "_" ] ; then
|
||||
ROUTER="_0"
|
||||
fi
|
||||
|
||||
#
|
||||
# That was the easy one, now for the tough one.
|
||||
#
|
||||
|
||||
CORE=$(cat ../../core/java/src/net/i2p/CoreVersion.java | grep -e "public final static String VERSION" | cut -f2 -d'"' | sed -re "s/ //g")
|
||||
CORE1=$(echo -n $CORE.x.x | sed -re "s/(.*)\.(.*)\.(.*)\.(.*)/\1/")
|
||||
CORE2=$(echo -n $CORE.x | sed -re "s/(.*)\.(.*)\.(.*)\.(.*)/\1/")
|
||||
|
||||
if [ "$CORE.x.x" == "$CORE1" ] ; then
|
||||
CORE=$(echo -ne $CORE".0.0")
|
||||
fi
|
||||
if [ "$CORE.x" == "$CORE2" ] ; then
|
||||
CORE=$(echo -ne $CORE".0")
|
||||
fi
|
||||
|
||||
VERSION=$(echo $CORE$ROUTER)
|
||||
#
|
||||
# Whew!
|
||||
# OK, let's build i2p
|
||||
#
|
||||
|
||||
CWD=$(pwd)
|
||||
CWD=$(readlink -m $(dirname $0))
|
||||
I2PSRC=$(readlink -m $CWD/../../)
|
||||
TMP=/tmp
|
||||
|
||||
PKG=$TMP/package-i2p
|
||||
rm -rf $PKG
|
||||
mkdir -p $PKG
|
||||
|
||||
cd $CWD/../../
|
||||
if [ -e "/etc/slackware-version" ]; then
|
||||
# Older than Slackware 13?
|
||||
SLACKVER=$(sed -e "s/Slackware\s\+\([0-9]\+\)\.\?\([0-9]\+\)\?/\1/" /etc/slackware-version)
|
||||
if [ $SLACKVER -lt 13 ] ; then
|
||||
EXT=tgz
|
||||
else
|
||||
EXT=txz
|
||||
fi
|
||||
else
|
||||
echo "ERROR: This script is only intended for use on Slackware systems.">&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract version strings
|
||||
I2PBUILD=$(sed -e '/^.\+long\s\+BUILD/!d' -e 's/^.\+long\s\+BUILD\s\+=\s\+\([0-9]\+\);/\1/' $I2PSRC/router/java/src/net/i2p/router/RouterVersion.java)
|
||||
# Thanks to user "ihavei2p" for the second awk statement
|
||||
# If the version is x.y, it'll be set to x.y.0. Otherwise the version string will be unchanged
|
||||
CORE=$(awk -F'"' '/static\s+String\s+VERSION/{print $2}' $I2PSRC/core/java/src/net/i2p/CoreVersion.java | \
|
||||
awk -F. '{ if (NF > 3) { print; exit } else if ($3 == "") { $3=0; print $1"."$2"."$3 } else print }')
|
||||
VERSION="${CORE}_${I2PBUILD}"
|
||||
|
||||
[ -d $PKG ] && rm -rf $PKG
|
||||
mkdir -p $PKG/$INSTALL_DIR $PKG/install
|
||||
|
||||
cd "$I2PSRC"
|
||||
ant distclean
|
||||
#ant dist
|
||||
ant tarball
|
||||
ant jbigi-linux-x86-only preppkg-unix
|
||||
|
||||
tar xjvf i2p.tar.bz2 -C $TMP
|
||||
chown -R root:root $I2PSRC/pkg-temp
|
||||
cp -a $I2PSRC/pkg-temp $PKG/$INSTALL_DIR/i2p
|
||||
|
||||
cd $TMP/i2p
|
||||
chown -R root:root .
|
||||
|
||||
mkdir -p $PKG/$INSTALL_DIR/
|
||||
cp -a ../i2p $PKG/$INSTALL_DIR/
|
||||
|
||||
mkdir -p $PKG/install
|
||||
|
||||
#############################################################################
|
||||
# Preconfigureation to make package smaller, and...
|
||||
# we keep as much as reasonable in the installation directory.
|
||||
# This makes the install map fairly well to the standard installation.
|
||||
# It also makes it easier to find the log and pid files!
|
||||
#############################################################################
|
||||
# $INSTALL_DIR is used by this SlackBuild.
|
||||
# [%$]INSTALL_PATH , [%$]SYSTEM_java_io_tmpdir, and [%$]USER_HOME have the correct paths set
|
||||
# by the IzPack installer.
|
||||
cd $PKG/$INSTALL_DIR/i2p
|
||||
for file in wrapper.config eepget i2prouter runplain.sh; do
|
||||
sed -i "s|[%$]INSTALL_PATH|/$INSTALL_DIR/i2p|g;s|[$%]SYSTEM_java_io_tmpdir|$TMP|g;s/[%$]USER_HOME/\$HOME/g" $file
|
||||
done
|
||||
mv wrapper.config wrapper.config.new
|
||||
|
||||
# wrapper.config $INSTALL_PATH and $SYSTEM_java_io_tmpdir
|
||||
sed "s|\$INSTALL_PATH|/$INSTALL_DIR/i2p|g" wrapper.config > a
|
||||
sed "s|\$SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > wrapper.config
|
||||
# eepget %INSTALL_PATH
|
||||
sed "s|\$INSTALL_PATH|/$INSTALL_DIR/i2p|g" eepget > a
|
||||
rm eepget
|
||||
mv a eepget
|
||||
# runplain.sh %INSTALL_PATH and %SYSTEM_java_io_tmpdir
|
||||
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" runplain.sh > a
|
||||
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > runplain.sh
|
||||
# i2prouter %INSTALL_PATH and %SYSTEM_java_io_tmpdir
|
||||
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" i2prouter > a
|
||||
rm i2prouter
|
||||
mv a i2prouter
|
||||
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" i2prouter > a
|
||||
sed "s|#ALLOW_ROOT=true|ALLOW_ROOT=true|g" a > i2prouter
|
||||
install -d $PKG/usr/bin
|
||||
install -d $PKG/usr/doc/$NAME-$VERSION
|
||||
install -d $PKG/etc/rc.d
|
||||
mv licenses LICENSE.txt -t $PKG/usr/doc/$NAME-$VERSION
|
||||
|
||||
chmod 744 ./i2prouter
|
||||
chmod 744 ./osid
|
||||
chmod 744 ./runplain.sh
|
||||
chmod 744 ./eepget
|
||||
chmod 744 ./scripts/i2pbench.sh
|
||||
chmod 744 ./scripts/i2ptest.sh
|
||||
rm -Rf ./lib/*.dll ./*.bat ./*.exe ./installer ./icons ./a postinstall.sh
|
||||
# runplain.sh will live in the installation directory. eepget and i2prouter will go to /usr/bin
|
||||
# with symlinks in INST_DIR (created in doinst.sh)
|
||||
install -m755 i2prouter $PKG/usr/bin
|
||||
install -m755 eepget $PKG/usr/bin
|
||||
chmod 755 ./runplain.sh
|
||||
|
||||
mv $PKG/$INSTALL_DIR/i2p/*.config $PKG/install
|
||||
mv $PKG/$INSTALL_DIR/i2p/blocklist.txt $PKG/$INSTALL_DIR/i2p/blocklist.txt.new
|
||||
find $PKG/$INSTALL_DIR/i2p -name "*.xml" -exec mv {} {}.new \;
|
||||
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html.new
|
||||
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico.new
|
||||
sed "s|directory|/$INSTALL_DIR/i2p/|g" $CWD/doinst.sh > $PKG/install/doinst.sh
|
||||
cat $CWD/slack-desc > $PKG/install/slack-desc
|
||||
if [ $INSTALL_DIR != 'opt' ]; then
|
||||
sed "s|\(The I2P package\)\s\+will be\s\+\(installed to\).+|\1 has been \2 $INSTALL_DIR/i2p|g" $CWD/README > $PKG/usr/doc/$NAME-$VERSION/README
|
||||
else
|
||||
sed "s|will be installed|has been installed|" $CWD/README > $PKG/usr/doc/$NAME-$VERSION/README
|
||||
fi
|
||||
|
||||
install -d $PKG/usr/man/man1
|
||||
gzip -9 man/*.1
|
||||
install -m644 man/*.1.gz $PKG/usr/man/man1
|
||||
rm -rf ./man
|
||||
|
||||
# We install all x86 wrapper binaries.
|
||||
# The i2prouter script will try to determine the OS (linux), the bits (32 VS 64) and should be able
|
||||
# to figure out the correct wrapper binary to use.
|
||||
|
||||
# However: In case the i2prouter script's detection fails, "$INST_DIR/i2psvc" will point to
|
||||
# what 'we' think the correct binary is.
|
||||
#
|
||||
# A good reason for installing all binaries: in case the user, for whatever reason, switches from an
|
||||
# x64 JRE to an x86 JRE, I2P should continue to work without needing to be reinstalled.
|
||||
install -m755 $I2PSRC/installer/lib/wrapper/linux/i2psvc ./i2psvc-linux-x86-32
|
||||
install -m644 $I2PSRC/installer/lib/wrapper/linux/libwrapper.so ./lib/libwrapper-linux-x86-32.so
|
||||
install -m755 $I2PSRC/installer/lib/wrapper/linux64/i2psvc ./i2psvc-linux-x86-64
|
||||
install -m644 $I2PSRC/installer/lib/wrapper/linux64/libwrapper.so ./lib/libwrapper-linux-x86-64.so
|
||||
install -m644 $I2PSRC/installer/lib/wrapper/all/wrapper.jar ./lib/wrapper.jar
|
||||
install -m644 $I2PSRC/build/jbigi.jar $PKG/$INSTALL_DIR/i2p/lib/jbigi.jar
|
||||
|
||||
rm -f ./postinstall.sh ./osid ./INSTALL-*.txt
|
||||
sed "s|directory|/$INSTALL_DIR/i2p|" $CWD/doinst.sh > $PKG/install/doinst.sh
|
||||
sed -i "s|%pkg|$NAME-$VERSION|" $PKG/install/doinst.sh
|
||||
sed "s|%INST_DIR|/$INSTALL_DIR/i2p|" $CWD/rc.i2p> $PKG/etc/rc.d/rc.i2p.new
|
||||
cp $CWD/slack-desc $PKG/install/slack-desc
|
||||
|
||||
cd $PKG
|
||||
#
|
||||
# requiredbuilder messes up REALLY bad, and thinks java is perl?!
|
||||
# It also did not catch the shell requirements! BOOOOOOOOOOO! HISSSSSSSS!
|
||||
#
|
||||
# requiredbuilder -v -y -s $CWD $PKG
|
||||
#
|
||||
cat $CWD/slack-required > $PKG/install/slack-required
|
||||
cp $CWD/slack-required $PKG/install/slack-required
|
||||
makepkg -l y -c n $CWD/${NAME}-$VERSION-$ARCH-$BUILD.$EXT
|
||||
|
185
Slackware/i2p/rc.i2p
Normal file
185
Slackware/i2p/rc.i2p
Normal file
@ -0,0 +1,185 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Abort on errors
|
||||
set -e
|
||||
|
||||
##
|
||||
# This *must* be configured. Set this to the user that will run I2P.
|
||||
# Note: If you don't want I2P to start automatically at boot,
|
||||
# use "i2prouter start" as a non-root user to start I2P.
|
||||
#RUN_AS_USER=
|
||||
##
|
||||
|
||||
##
|
||||
# Set the locale as desired.
|
||||
# Note: this is not the same as the language shown in the I2P router console.
|
||||
# This affects the locale used in wrapper.log. For best results, use a
|
||||
# unicode enabled locale. This is especially important for foreign language torrents.
|
||||
#
|
||||
# If not set the user's configured locale will be used.
|
||||
#RCLOCALE=
|
||||
##
|
||||
|
||||
#####################################################
|
||||
# Nothing below this point should need to be edited #
|
||||
#####################################################
|
||||
# %INST_DIR is set by i2p.SlackBuild
|
||||
INSTALL_DIR="%INST_DIR"
|
||||
# Make sure the package is installed and that the wrapper can be found
|
||||
[ -d $INSTALL_DIR ] && [ -x $INSTALL_DIR/i2psvc ] || (echo "The I2P package is not installed" >&2 ; exit 1)
|
||||
|
||||
if [ -z $RUN_AS_USER ]; then
|
||||
echo "ERROR: RUN_AS_USER not configured in $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $(id -ur) -ne 0 ]; then
|
||||
echo 'ERROR: You must be root to start this service.' >&2
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $RCLOCALE ]; then
|
||||
if [ ! $(locale -a |grep -q "en_US\.utf8") ]; then
|
||||
RCLOCALE="en_US.utf8"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Abort this script if any referenced variables haven't been set
|
||||
set -u
|
||||
|
||||
if $(uname -m |grep -q '64'); then
|
||||
BITS='64'
|
||||
else
|
||||
BITS=''
|
||||
fi
|
||||
|
||||
PATH="$PATH:/usr/lib$BITS/java/bin:/usr/lib$BITS/java/jre/bin"
|
||||
RUN=/var/run/i2p
|
||||
PIDFILE="$RUN/i2p.pid"
|
||||
WRAPPER_CONF="$INSTALL_DIR/wrapper.config"
|
||||
WRAPPERLOG=/var/log/i2p/wrapper.log
|
||||
I2PTEMP="/tmp/i2p-daemon"
|
||||
DESC="The I2P daemon"
|
||||
JAVABINARY=$(awk -F'=' '/^ *wrapper\.java\.command/{print $2}' "$WRAPPER_CONF")
|
||||
|
||||
if [ ! $(which $JAVABINARY 2>/dev/null) ]; then
|
||||
for rc in /etc/profile.d/*jdk*.sh /etc/profile.d/*java*.sh; do
|
||||
[ -r $rc ] && . $rc
|
||||
done
|
||||
if [ ! $(which $JAVABINARY 2>/dev/null) ]; then
|
||||
echo "ERROR: Cannot find java. Please set the path to java in $WRAPPER_CONF" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
JAVA=$(which $JAVABINARY 2>/dev/null)
|
||||
|
||||
I2P_ARGS="$WRAPPER_CONF \
|
||||
wrapper.java.additional.1=-DloggerFilenameOverride=/var/log/i2p/log-router-@.txt \
|
||||
wrapper.java.additional.10=-Dwrapper.logfile=$WRAPPERLOG \
|
||||
wrapper.java.additional.11=-Di2p.dir.pid=$RUN \
|
||||
wrapper.java.additional.12=-Di2p.dir.temp=$I2PTEMP \
|
||||
wrapper.java.command=$JAVA \
|
||||
wrapper.logfile=$WRAPPERLOG \
|
||||
wrapper.pidfile=$PIDFILE \
|
||||
wrapper.daemonize=TRUE"
|
||||
|
||||
LC_ALL=$RCLOCALE
|
||||
LANG=$RCLOCALE
|
||||
export LC_ALL LANG
|
||||
|
||||
is_running() {
|
||||
if [ -r $PIDFILE ]; then
|
||||
PID="$(cat ${PIDFILE})" 2>/dev/null 2>&1
|
||||
if ! kill -0 $PID >/dev/null 2>&1; then
|
||||
rm "$PIDFILE"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
if is_running; then
|
||||
echo "ERROR: $DESC is already running." >&2
|
||||
fi
|
||||
|
||||
for DIR in $RUN $I2PTEMP; do
|
||||
test -d $DIR && rm -rf $DIR
|
||||
mkdir -p $DIR
|
||||
chown -R $RUN_AS_USER $DIR
|
||||
done
|
||||
[ -d /var/log/i2p ] || mkdir /var/log/i2p
|
||||
chown -R $RUN_AS_USER /var/log/i2p
|
||||
|
||||
echo -n "Starting $DESC..."
|
||||
TZ=UTC su $RUN_AS_USER -c "$INSTALL_DIR/i2psvc $I2P_ARGS"
|
||||
is_running
|
||||
echo "[pid: $PID]"
|
||||
}
|
||||
|
||||
stop(){
|
||||
if is_running; then
|
||||
echo -n "Stopping $DESC [pid: $PID] (this could take a while)."
|
||||
kill "$PID" >/dev/null 2>&1
|
||||
while kill -0 "$PID" > /dev/null 2>&1; do
|
||||
echo -n .
|
||||
sleep 1
|
||||
done
|
||||
rm -rf "$RUN" "$I2PTEMP"
|
||||
echo done.
|
||||
return 0
|
||||
else
|
||||
echo "$DESC is not running." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Unset +u to allow the 'usage' text to be displayed
|
||||
set +u
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
status)
|
||||
if is_running; then
|
||||
echo "$DESC is running [pid: $PID]" >&2
|
||||
else
|
||||
echo "$DESC is not running." >&2
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
graceful)
|
||||
if is_running; then
|
||||
kill -HUP $PID
|
||||
echo "Graceful shutdown of $DESC initiated." >&2
|
||||
echo "This may take up to 11 minutes." >&2
|
||||
fi
|
||||
;;
|
||||
dump)
|
||||
if is_running; then
|
||||
kill -3 $PID
|
||||
echo "Threads dumped to $WRAPPERLOG" >&2
|
||||
else
|
||||
echo "$DESC is not running." >&2
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
if is_running; then
|
||||
stop
|
||||
start
|
||||
else
|
||||
echo "$DESC is not running." >&2
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 start|stop|status|restart|graceful|dump"
|
||||
;;
|
||||
esac
|
@ -1,47 +0,0 @@
|
||||
Building:
|
||||
The i2p package will be installed in /opt/i2p
|
||||
|
||||
If you want to change installation dir, change the variable INSTALL_DIR
|
||||
on i2p.SlackBuild and rebuild the package. You will also need to do the same
|
||||
in the base-i2p package.
|
||||
|
||||
Installation and Upgrade:
|
||||
Probably you will never have to update i2p packages. However if you do,
|
||||
be sure to installpkg first, then removepkg or custom config files can
|
||||
be lost with upgradepkg. I2P has an auto-update function. However using
|
||||
installpkg then removepkg lowers the demand on the I2P network as a
|
||||
whole, and is by far faster.
|
||||
|
||||
After installpkg command, doinst.sh will execute a postinstallation script
|
||||
needed by I2P. Be sure to also install the base-i2p package.
|
||||
|
||||
Optional:
|
||||
|
||||
chmod +x /etc/rc.d/rc.i2p only if you want it to start on boot and stop on
|
||||
shutdown.
|
||||
|
||||
How to start I2P:
|
||||
|
||||
Start I2P service with-
|
||||
sh /etc/rc.d/rc.i2p start
|
||||
|
||||
Now tell your browser to user this proxy: localhost on port 4444 and open
|
||||
this page: http://localhost:7657/index.jsp
|
||||
Here you can configure I2P, watch network status and navigate anonimously.
|
||||
It's suggested to subscribe to various addressbook hosts so that you can
|
||||
get to the many available eepsites and other service on I2P. These are not
|
||||
set up by default for security reasons.
|
||||
|
||||
Please see the faqs on http://www.i2p2.i2p/ or http://www.i2p2.de/ on how
|
||||
to subscribe to the various addressbook services.
|
||||
|
||||
To stop I2P:
|
||||
/etc/rc.d/rc.i2p stop
|
||||
|
||||
|
||||
For any additional information:
|
||||
|
||||
Within I2P- http://www.i2p2.i2p/, http://forum.i2p/, http://zzz.i2p
|
||||
|
||||
Internet (not reccomended!) - http://www.i2p2.de/, http://forum.i2p2.de/
|
||||
|
@ -6,7 +6,7 @@
|
||||
# leave one space after the ':'.
|
||||
|
||||
|-----handy-ruler----------------------------------------------------------|
|
||||
i2p: i2p (an anonymizing network)
|
||||
i2p: I2P (an anonymizing network)
|
||||
i2p:
|
||||
i2p: I2P is an anonymizing network, offering a simple layer that
|
||||
i2p: identity-sensitive applications can use to securely communicate. All
|
||||
@ -14,6 +14,6 @@ i2p: data is wrapped with several layers of encryption, and the network is
|
||||
i2p: both distributed and dynamic, with no trusted parties.
|
||||
i2p: Many applications are available that interface with I2P, including
|
||||
i2p: mail, peer-peer file sharing, IRC chat, and others.
|
||||
i2p: WARNING: To upgrade installpkg FIRST _THEN_ removepkg.
|
||||
i2p: For more information, see: http://www.i2p2.de/
|
||||
i2p:
|
||||
i2p: For more information, see: https://geti2p.net/
|
||||
i2p:
|
||||
|
@ -1,4 +1 @@
|
||||
jre >= 5
|
||||
i2p-base >= 0.0.1
|
||||
bash >= 3.1.017
|
||||
|
||||
jre >= 6
|
||||
|
8
apps/BOB/.classpath
Normal file
8
apps/BOB/.classpath
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/ministreaming"/>
|
||||
<classpathentry kind="output" path="build"/>
|
||||
</classpath>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>lib</name>
|
||||
<name>BOB</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
@ -66,7 +66,7 @@ public class Main {
|
||||
}
|
||||
|
||||
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
||||
CMDout.write(s.getBytes());
|
||||
CMDout.write(DataHelper.getUTF8(s));
|
||||
CMDout.write('\n');
|
||||
CMDout.flush();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class Main {
|
||||
}
|
||||
|
||||
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
||||
CMDout.write(s.getBytes());
|
||||
CMDout.write(DataHelper.getUTF8(s));
|
||||
CMDout.write('\n');
|
||||
CMDout.flush();
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package net.i2p.BOB;
|
||||
|
||||
import static net.i2p.app.ClientAppState.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -25,13 +27,17 @@ import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.*;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
|
||||
/**
|
||||
@ -105,57 +111,78 @@ import net.i2p.util.SimpleTimer2;
|
||||
*
|
||||
* @author sponge
|
||||
*/
|
||||
public class BOB {
|
||||
public class BOB implements Runnable, ClientApp {
|
||||
|
||||
public final static String PROP_CONFIG_LOCATION = "BOB.config";
|
||||
public final static String PROP_BOB_PORT = "BOB.port";
|
||||
public final static String PROP_BOB_HOST = "BOB.host";
|
||||
public final static String PROP_CFG_VER = "BOB.CFG.VER";
|
||||
private static NamedDB database;
|
||||
private static Properties props = new Properties();
|
||||
private static AtomicBoolean spin = new AtomicBoolean(true);
|
||||
|
||||
/** unused when started via the ClientApp interface */
|
||||
private static BOB _bob;
|
||||
|
||||
private final NamedDB database;
|
||||
private final Properties props = new Properties();
|
||||
private final AtomicBoolean spin = new AtomicBoolean(true);
|
||||
private static final String P_RUNNING = "RUNNING";
|
||||
private static final String P_STARTING = "STARTING";
|
||||
private static final String P_STOPPING = "STOPPING";
|
||||
private static AtomicBoolean lock = new AtomicBoolean(false);
|
||||
private final AtomicBoolean lock = new AtomicBoolean(false);
|
||||
// no longer used.
|
||||
// private static int maxConnections = 0;
|
||||
|
||||
/**
|
||||
* Log a warning
|
||||
*
|
||||
* @param arg
|
||||
*/
|
||||
public static void info(String arg) {
|
||||
System.out.println("INFO:" + arg);
|
||||
(new Log(BOB.class)).info(arg);
|
||||
}
|
||||
private final Logger _log;
|
||||
private final ClientAppManager _mgr;
|
||||
private final String[] _args;
|
||||
private volatile ClientAppState _state = UNINITIALIZED;
|
||||
|
||||
/**
|
||||
* Log a warning
|
||||
*
|
||||
* @param arg
|
||||
*/
|
||||
public static void warn(String arg) {
|
||||
System.out.println("WARNING:" + arg);
|
||||
(new Log(BOB.class)).warn(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error
|
||||
*
|
||||
* @param arg
|
||||
*/
|
||||
public static void error(String arg) {
|
||||
System.out.println("ERROR: " + arg);
|
||||
(new Log(BOB.class)).error(arg);
|
||||
}
|
||||
private volatile ServerSocket listener;
|
||||
private volatile Thread _runner;
|
||||
|
||||
/**
|
||||
* Stop BOB gracefully
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static void stop() {
|
||||
spin.set(false);
|
||||
public synchronized static void stop() {
|
||||
if (_bob != null)
|
||||
_bob.shutdown(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* For ClientApp interface.
|
||||
* Does NOT open the listener socket or start threads; caller must call startup()
|
||||
*
|
||||
* @param mgr may be null
|
||||
* @param args non-null
|
||||
* @throws Exception on bad args
|
||||
* @since 0.9.10
|
||||
*/
|
||||
public BOB(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
||||
// If we were run from command line, log to stdout
|
||||
boolean logToStdout = false;
|
||||
URL classResource = BOB.class.getResource("BOB.class");
|
||||
if (classResource != null) {
|
||||
String classPath = classResource.toString();
|
||||
if (classPath.startsWith("jar")) {
|
||||
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
|
||||
"/META-INF/MANIFEST.MF";
|
||||
try {
|
||||
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
|
||||
Attributes attrs = manifest.getMainAttributes();
|
||||
String mainClass = attrs.getValue("Main-Class");
|
||||
if ("net.i2p.BOB.Main".equals(mainClass))
|
||||
logToStdout = true;
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
_log = new Logger(context.logManager().getLog(BOB.class), logToStdout);
|
||||
|
||||
_mgr = mgr;
|
||||
_args = args;
|
||||
_state = INITIALIZED;
|
||||
database = new NamedDB();
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,129 +190,169 @@ public class BOB {
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
database = new NamedDB();
|
||||
ServerSocket listener = null;
|
||||
public synchronized static void main(String[] args) {
|
||||
try {
|
||||
_bob = new BOB(I2PAppContext.getGlobalContext(), null, args);
|
||||
_bob.startup();
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
private void loadConfig() {
|
||||
int i = 0;
|
||||
boolean save = false;
|
||||
// Set up all defaults to be passed forward to other threads.
|
||||
// Re-reading the config file in each thread is pretty damn stupid.
|
||||
String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config");
|
||||
// This is here just to ensure there is no interference with our threadgroups.
|
||||
SimpleScheduler Y1 = SimpleScheduler.getInstance();
|
||||
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
||||
i = Y1.hashCode();
|
||||
i = Y2.hashCode();
|
||||
Log _log = new Log(BOB.class);
|
||||
try {
|
||||
{
|
||||
File cfg = new File(configLocation);
|
||||
if (!cfg.isAbsolute()) {
|
||||
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
|
||||
}
|
||||
try {
|
||||
FileInputStream fi = new FileInputStream(cfg);
|
||||
props.load(fi);
|
||||
fi.close();
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
warn("Unable to load up the BOB config file " + cfg.getAbsolutePath() + ", Using defaults.");
|
||||
warn(fnfe.toString());
|
||||
save = true;
|
||||
} catch (IOException ioe) {
|
||||
warn("IOException on BOB config file " + cfg.getAbsolutePath() + ", using defaults.");
|
||||
warn(ioe.toString());
|
||||
}
|
||||
{
|
||||
File cfg = new File(configLocation);
|
||||
if (!cfg.isAbsolute()) {
|
||||
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
|
||||
}
|
||||
// Global router and client API configurations that are missing are set to defaults here.
|
||||
if (!props.containsKey(I2PClient.PROP_TCP_HOST)) {
|
||||
props.setProperty(I2PClient.PROP_TCP_HOST, "localhost");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(I2PClient.PROP_TCP_PORT)) {
|
||||
props.setProperty(I2PClient.PROP_TCP_PORT, "7654");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(PROP_BOB_PORT)) {
|
||||
props.setProperty(PROP_BOB_PORT, "2827"); // 0xB0B
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("inbound.length")) {
|
||||
props.setProperty("inbound.length", "1");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("outbound.length")) {
|
||||
props.setProperty("outbound.length", "1");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("inbound.lengthVariance")) {
|
||||
props.setProperty("inbound.lengthVariance", "0");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("outbound.lengthVariance")) {
|
||||
props.setProperty("outbound.lengthVariance", "0");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(PROP_BOB_HOST)) {
|
||||
props.setProperty(PROP_BOB_HOST, "localhost");
|
||||
save = true;
|
||||
}
|
||||
// PROP_RELIABILITY_NONE, PROP_RELIABILITY_BEST_EFFORT, PROP_RELIABILITY_GUARANTEED
|
||||
if (!props.containsKey(PROP_CFG_VER)) {
|
||||
props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
|
||||
props.setProperty(PROP_CFG_VER,"1");
|
||||
save = true;
|
||||
}
|
||||
if (save) {
|
||||
File cfg = new File(configLocation);
|
||||
if (!cfg.isAbsolute()) {
|
||||
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
|
||||
}
|
||||
try {
|
||||
warn("Writing new defaults file " + cfg.getAbsolutePath());
|
||||
FileOutputStream fo = new FileOutputStream(cfg);
|
||||
props.store(fo, cfg.getAbsolutePath());
|
||||
fo.close();
|
||||
} catch (IOException ioe) {
|
||||
error("IOException on BOB config file " + cfg.getAbsolutePath() + ", " + ioe);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
boolean g = false;
|
||||
spin.set(true);
|
||||
FileInputStream fi = null;
|
||||
try {
|
||||
info("BOB is now running.");
|
||||
listener = new ServerSocket(Integer.parseInt(props.getProperty(PROP_BOB_PORT)), 10, InetAddress.getByName(props.getProperty(PROP_BOB_HOST)));
|
||||
Socket server = null;
|
||||
listener.setSoTimeout(500); // .5 sec
|
||||
|
||||
while (spin.get()) {
|
||||
//DoCMDS connection;
|
||||
|
||||
try {
|
||||
server = listener.accept();
|
||||
server.setKeepAlive(true);
|
||||
g = true;
|
||||
} catch (ConnectException ce) {
|
||||
g = false;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
|
||||
if (g) {
|
||||
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
|
||||
Thread t = new Thread(conn_c);
|
||||
t.setName("BOB.DoCMDS " + i);
|
||||
t.start();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
fi = new FileInputStream(cfg);
|
||||
props.load(fi);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
_log.warn("Unable to load up the BOB config file " + cfg.getAbsolutePath() + ", Using defaults.", fnfe);
|
||||
save = true;
|
||||
} catch (IOException ioe) {
|
||||
error("IOException on socket listen: " + ioe);
|
||||
ioe.printStackTrace();
|
||||
_log.warn("IOException on BOB config file " + cfg.getAbsolutePath() + ", using defaults.", ioe);
|
||||
} finally {
|
||||
if (fi != null) try { fi.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
// Global router and client API configurations that are missing are set to defaults here.
|
||||
if (!props.containsKey(I2PClient.PROP_TCP_HOST)) {
|
||||
props.setProperty(I2PClient.PROP_TCP_HOST, "localhost");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(I2PClient.PROP_TCP_PORT)) {
|
||||
props.setProperty(I2PClient.PROP_TCP_PORT, "7654");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(PROP_BOB_PORT)) {
|
||||
props.setProperty(PROP_BOB_PORT, "2827"); // 0xB0B
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("inbound.length")) {
|
||||
props.setProperty("inbound.length", "3");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("outbound.length")) {
|
||||
props.setProperty("outbound.length", "3");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("inbound.lengthVariance")) {
|
||||
props.setProperty("inbound.lengthVariance", "0");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey("outbound.lengthVariance")) {
|
||||
props.setProperty("outbound.lengthVariance", "0");
|
||||
save = true;
|
||||
}
|
||||
if (!props.containsKey(PROP_BOB_HOST)) {
|
||||
props.setProperty(PROP_BOB_HOST, "localhost");
|
||||
save = true;
|
||||
}
|
||||
// PROP_RELIABILITY_NONE, PROP_RELIABILITY_BEST_EFFORT, PROP_RELIABILITY_GUARANTEED
|
||||
if (!props.containsKey(PROP_CFG_VER)) {
|
||||
props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
|
||||
props.setProperty(PROP_CFG_VER,"1");
|
||||
save = true;
|
||||
}
|
||||
if (save) {
|
||||
File cfg = new File(configLocation);
|
||||
if (!cfg.isAbsolute()) {
|
||||
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
|
||||
}
|
||||
FileOutputStream fo = null;
|
||||
try {
|
||||
_log.warn("Writing new defaults file " + cfg.getAbsolutePath());
|
||||
fo = new FileOutputStream(cfg);
|
||||
props.store(fo, cfg.getAbsolutePath());
|
||||
} catch (IOException ioe) {
|
||||
_log.error("IOException on BOB config file " + cfg.getAbsolutePath(), ioe);
|
||||
} finally {
|
||||
if (fo != null) try { fo.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
private void startListener() throws IOException {
|
||||
listener = new ServerSocket(Integer.parseInt(props.getProperty(PROP_BOB_PORT)), 10, InetAddress.getByName(props.getProperty(PROP_BOB_HOST)));
|
||||
listener.setSoTimeout(500); // .5 sec
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
private void startThread() {
|
||||
I2PAppThread t = new I2PAppThread(this, "BOBListener");
|
||||
t.start();
|
||||
_runner = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
public void run() {
|
||||
if (listener == null) return;
|
||||
changeState(RUNNING);
|
||||
_log.info("BOB is now running.");
|
||||
if (_mgr != null)
|
||||
_mgr.register(this);
|
||||
|
||||
int i = 0;
|
||||
boolean g = false;
|
||||
spin.set(true);
|
||||
try {
|
||||
Socket server = null;
|
||||
|
||||
while (spin.get()) {
|
||||
//DoCMDS connection;
|
||||
|
||||
try {
|
||||
server = listener.accept();
|
||||
server.setKeepAlive(true);
|
||||
g = true;
|
||||
} catch (ConnectException ce) {
|
||||
g = false;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
|
||||
if (g) {
|
||||
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
|
||||
Thread t = new I2PAppThread(conn_c);
|
||||
t.setName("BOB.DoCMDS " + i);
|
||||
t.start();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
changeState(STOPPING);
|
||||
} catch (Exception e) {
|
||||
if (spin.get())
|
||||
_log.error("Unexpected error while listening for connections", e);
|
||||
else
|
||||
e = null;
|
||||
changeState(STOPPING, e);
|
||||
} finally {
|
||||
info("BOB is now shutting down...");
|
||||
_log.info("BOB is now shutting down...");
|
||||
// Clean up everything.
|
||||
try {
|
||||
listener.close();
|
||||
@ -308,7 +375,7 @@ public class BOB {
|
||||
database.releaseReadLock();
|
||||
database.getWriteLock();
|
||||
nickinfo.getWriteLock();
|
||||
nickinfo.add(P_STOPPING, new Boolean(true));
|
||||
nickinfo.add(P_STOPPING, Boolean.valueOf(true));
|
||||
nickinfo.releaseWriteLock();
|
||||
database.releaseWriteLock();
|
||||
} else {
|
||||
@ -316,8 +383,8 @@ public class BOB {
|
||||
database.releaseReadLock();
|
||||
}
|
||||
}
|
||||
info("BOB is now stopped.");
|
||||
|
||||
changeState(STOPPED);
|
||||
_log.info("BOB is now stopped.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,4 +436,86 @@ public class BOB {
|
||||
waitjoin(groups[i], level + 1, groups[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
////// begin ClientApp interface
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
@Override
|
||||
public void startup() throws IOException {
|
||||
if (_state != INITIALIZED)
|
||||
return;
|
||||
changeState(STARTING);
|
||||
try {
|
||||
startListener();
|
||||
} catch (IOException e) {
|
||||
_log.error("Error starting BOB on"
|
||||
+ props.getProperty(PROP_BOB_HOST)
|
||||
+ ":" + props.getProperty(PROP_BOB_PORT), e);
|
||||
changeState(START_FAILED, e);
|
||||
throw e;
|
||||
}
|
||||
startThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
@Override
|
||||
public void shutdown(String[] args) {
|
||||
if (_state != RUNNING)
|
||||
return;
|
||||
changeState(STOPPING);
|
||||
spin.set(false);
|
||||
if (_runner != null)
|
||||
_runner.interrupt();
|
||||
else
|
||||
changeState(STOPPED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
@Override
|
||||
public ClientAppState getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "BOB";
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "BOB " + Arrays.toString(_args);
|
||||
}
|
||||
|
||||
////// end ClientApp interface
|
||||
////// begin ClientApp helpers
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
private void changeState(ClientAppState state) {
|
||||
changeState(state, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.10
|
||||
*/
|
||||
private synchronized void changeState(ClientAppState state, Exception e) {
|
||||
_state = state;
|
||||
if (_mgr != null)
|
||||
_mgr.notify(this, state, null, e);
|
||||
}
|
||||
|
||||
////// end ClientApp helpers
|
||||
}
|
||||
|
@ -25,13 +25,13 @@ import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
//import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
//import net.i2p.i2ptunnel.I2PTunnel;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
// needed only for debugging.
|
||||
// import java.util.logging.Level;
|
||||
// import java.util.logging.Logger;
|
||||
@ -56,7 +56,7 @@ public class DoCMDS implements Runnable {
|
||||
private ByteArrayOutputStream prikey;
|
||||
private boolean dk, ns, ip, op;
|
||||
private NamedDB nickinfo;
|
||||
private Log _log;
|
||||
private Logger _log;
|
||||
private AtomicBoolean LIVE;
|
||||
private AtomicBoolean lock;
|
||||
/* database strings */
|
||||
@ -164,7 +164,7 @@ public class DoCMDS implements Runnable {
|
||||
* @param database
|
||||
* @param _log
|
||||
*/
|
||||
DoCMDS(AtomicBoolean LIVE, AtomicBoolean lock, Socket server, Properties props, NamedDB database, Log _log) {
|
||||
DoCMDS(AtomicBoolean LIVE, AtomicBoolean lock, Socket server, Properties props, NamedDB database, Logger _log) {
|
||||
this.lock = lock;
|
||||
this.LIVE = LIVE;
|
||||
this.server = server;
|
||||
@ -606,7 +606,7 @@ public class DoCMDS implements Runnable {
|
||||
break die;
|
||||
}
|
||||
} catch (I2PException ipe) {
|
||||
BOB.error("Error generating keys" + ipe);
|
||||
_log.error("Error generating keys", ipe);
|
||||
out.println("ERROR generating keys");
|
||||
}
|
||||
|
||||
@ -665,7 +665,7 @@ public class DoCMDS implements Runnable {
|
||||
break die;
|
||||
}
|
||||
try {
|
||||
nickinfo.add(P_QUIET, new Boolean(Boolean.parseBoolean(Arg) == true));
|
||||
nickinfo.add(P_QUIET, Boolean.valueOf(Arg));
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
wunlock();
|
||||
@ -817,10 +817,10 @@ public class DoCMDS implements Runnable {
|
||||
try {
|
||||
database.add(Arg, nickinfo);
|
||||
nickinfo.add(P_NICKNAME, Arg);
|
||||
nickinfo.add(P_STARTING, new Boolean(false));
|
||||
nickinfo.add(P_RUNNING, new Boolean(false));
|
||||
nickinfo.add(P_STOPPING, new Boolean(false));
|
||||
nickinfo.add(P_QUIET, new Boolean(false));
|
||||
nickinfo.add(P_STARTING, Boolean.valueOf(false));
|
||||
nickinfo.add(P_RUNNING, Boolean.valueOf(false));
|
||||
nickinfo.add(P_STOPPING, Boolean.valueOf(false));
|
||||
nickinfo.add(P_QUIET, Boolean.valueOf(false));
|
||||
nickinfo.add(P_INHOST, "localhost");
|
||||
nickinfo.add(P_OUTHOST, "localhost");
|
||||
Properties Q = new Properties();
|
||||
@ -989,7 +989,7 @@ public class DoCMDS implements Runnable {
|
||||
prt = Integer.parseInt(Arg);
|
||||
if (prt > 1 && prt < 65536) {
|
||||
try {
|
||||
nickinfo.add(P_INPORT, new Integer(prt));
|
||||
nickinfo.add(P_INPORT, Integer.valueOf(prt));
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
wunlock();
|
||||
@ -1076,7 +1076,7 @@ public class DoCMDS implements Runnable {
|
||||
prt = Integer.parseInt(Arg);
|
||||
if (prt > 1 && prt < 65536) {
|
||||
try {
|
||||
nickinfo.add(P_OUTPORT, new Integer(prt));
|
||||
nickinfo.add(P_OUTPORT, Integer.valueOf(prt));
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
wunlock();
|
||||
@ -1308,7 +1308,7 @@ public class DoCMDS implements Runnable {
|
||||
// wait
|
||||
}
|
||||
tunnel = new MUXlisten(lock, database, nickinfo, _log);
|
||||
Thread t = new Thread(tunnel);
|
||||
Thread t = new I2PAppThread(tunnel);
|
||||
t.start();
|
||||
// try {
|
||||
// Thread.sleep(1000 * 10); // Slow down the startup.
|
||||
@ -1355,7 +1355,7 @@ public class DoCMDS implements Runnable {
|
||||
break die;
|
||||
}
|
||||
|
||||
nickinfo.add(P_STOPPING, new Boolean(true));
|
||||
nickinfo.add(P_STOPPING, Boolean.valueOf(true));
|
||||
try {
|
||||
wunlock();
|
||||
|
||||
|
@ -18,11 +18,12 @@ package net.i2p.BOB;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
* Listen on I2P and connect to TCP
|
||||
@ -31,25 +32,23 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class I2Plistener implements Runnable {
|
||||
|
||||
private NamedDB info, database;
|
||||
private Log _log;
|
||||
public I2PSocketManager socketManager;
|
||||
public I2PServerSocket serverSocket;
|
||||
private AtomicBoolean lives;
|
||||
private final NamedDB info, database;
|
||||
private final Logger _log;
|
||||
private final I2PServerSocket serverSocket;
|
||||
private final AtomicBoolean lives;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param SS
|
||||
* @param S
|
||||
* @param S unused
|
||||
* @param info
|
||||
* @param database
|
||||
* @param _log
|
||||
*/
|
||||
I2Plistener(I2PServerSocket SS, I2PSocketManager S, NamedDB info, NamedDB database, Log _log, AtomicBoolean lives) {
|
||||
I2Plistener(I2PServerSocket SS, I2PSocketManager S, NamedDB info, NamedDB database, Logger _log, AtomicBoolean lives) {
|
||||
this.database = database;
|
||||
this.info = info;
|
||||
this._log = _log;
|
||||
this.socketManager = S;
|
||||
this.serverSocket = SS;
|
||||
this.lives = lives;
|
||||
}
|
||||
@ -80,7 +79,7 @@ public class I2Plistener implements Runnable {
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn);
|
||||
Thread t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn);
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,10 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
* Process I2P->TCP
|
||||
@ -104,15 +107,15 @@ public class I2PtoTCP implements Runnable {
|
||||
|
||||
if (tell) {
|
||||
// tell who is connecting
|
||||
out.write(I2P.getPeerDestination().toBase64().getBytes());
|
||||
out.write(DataHelper.getASCII(I2P.getPeerDestination().toBase64()));
|
||||
out.write(10); // nl
|
||||
out.flush(); // not really needed, but...
|
||||
}
|
||||
// setup to cross the streams
|
||||
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
||||
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
||||
t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||
q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||
// Fire!
|
||||
t.start();
|
||||
q.start();
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package net.i2p.BOB;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
@ -39,10 +39,8 @@ public class Lifted {
|
||||
*
|
||||
**/
|
||||
public static void copyProperties(Properties src_prop, Properties dest_prop) {
|
||||
for (Enumeration propertyNames = src_prop.propertyNames();
|
||||
propertyNames.hasMoreElements();) {
|
||||
Object key = propertyNames.nextElement();
|
||||
dest_prop.put(key, src_prop.get(key));
|
||||
for (Map.Entry<Object, Object> e : src_prop.entrySet()) {
|
||||
dest_prop.put((String)e.getKey(), (String)e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
apps/BOB/src/net/i2p/BOB/Logger.java
Normal file
44
apps/BOB/src/net/i2p/BOB/Logger.java
Normal file
@ -0,0 +1,44 @@
|
||||
package net.i2p.BOB;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class Logger {
|
||||
public Log log;
|
||||
private boolean logToStdout;
|
||||
|
||||
public Logger(Log log, boolean logToStdout) {
|
||||
this.log = log;
|
||||
this.logToStdout = logToStdout;
|
||||
}
|
||||
|
||||
public void info(String msg) {
|
||||
if (logToStdout)
|
||||
System.out.println("INFO: " + msg);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info(msg);
|
||||
}
|
||||
|
||||
public void warn(String msg) {
|
||||
warn(msg, null);
|
||||
}
|
||||
|
||||
public void warn(String msg, Throwable e) {
|
||||
if (logToStdout) {
|
||||
System.out.println("WARNING: " + msg);
|
||||
if (e != null)
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn(msg, e);
|
||||
}
|
||||
|
||||
public void error(String msg, Throwable e) {
|
||||
if (logToStdout) {
|
||||
System.out.println("ERROR: " + msg);
|
||||
if (e != null)
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (log.shouldLog(Log.ERROR))
|
||||
log.error(msg, e);
|
||||
}
|
||||
}
|
@ -21,10 +21,13 @@ import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -36,7 +39,7 @@ import net.i2p.util.Log;
|
||||
public class MUXlisten implements Runnable {
|
||||
|
||||
private NamedDB database, info;
|
||||
private Log _log;
|
||||
private Logger _log;
|
||||
private I2PSocketManager socketManager;
|
||||
private ByteArrayInputStream prikey;
|
||||
private ThreadGroup tg;
|
||||
@ -57,7 +60,7 @@ public class MUXlisten implements Runnable {
|
||||
* @throws net.i2p.I2PException
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
MUXlisten(AtomicBoolean lock, NamedDB database, NamedDB info, Log _log) throws I2PException, IOException, RuntimeException {
|
||||
MUXlisten(AtomicBoolean lock, NamedDB database, NamedDB info, Logger _log) throws I2PException, IOException, RuntimeException {
|
||||
try {
|
||||
int port = 0;
|
||||
InetAddress host = null;
|
||||
@ -70,7 +73,7 @@ public class MUXlisten implements Runnable {
|
||||
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", new Boolean(true));
|
||||
this.info.add("STARTING", Boolean.valueOf(true));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
this.database.getReadLock();
|
||||
@ -96,15 +99,25 @@ public class MUXlisten implements Runnable {
|
||||
this.database.releaseReadLock();
|
||||
this.info.releaseReadLock();
|
||||
|
||||
String i2cpHost = Q.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
|
||||
int i2cpPort = 7654;
|
||||
String i2cpPortStr = Q.getProperty(I2PClient.PROP_TCP_PORT, "7654");
|
||||
try {
|
||||
i2cpPort = Integer.parseInt(i2cpPortStr);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException("Invalid I2CP port specified [" + i2cpPortStr + "]");
|
||||
}
|
||||
|
||||
if (this.come_in) {
|
||||
this.listener = new ServerSocket(port, backlog, host);
|
||||
}
|
||||
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
||||
socketManager = I2PSocketManagerFactory.createManager(
|
||||
prikey, i2cpHost, i2cpPort, Q);
|
||||
} catch (IOException e) {
|
||||
// Something went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", new Boolean(false));
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
throw new IOException(e.toString());
|
||||
@ -112,7 +125,7 @@ public class MUXlisten implements Runnable {
|
||||
// Something went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", new Boolean(false));
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
throw new RuntimeException(e);
|
||||
@ -120,7 +133,7 @@ public class MUXlisten implements Runnable {
|
||||
// Something else went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", new Boolean(false));
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
e.printStackTrace();
|
||||
@ -160,7 +173,7 @@ public class MUXlisten implements Runnable {
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("RUNNING", new Boolean(true));
|
||||
info.add("RUNNING", Boolean.valueOf(true));
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
@ -190,21 +203,21 @@ public class MUXlisten implements Runnable {
|
||||
// I2P -> TCP
|
||||
SS = socketManager.getServerSocket();
|
||||
I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log, lives);
|
||||
t = new Thread(tg, conn, "BOBI2Plistener " + N);
|
||||
t = new I2PAppThread(tg, conn, "BOBI2Plistener " + N);
|
||||
t.start();
|
||||
}
|
||||
|
||||
if (come_in) {
|
||||
// TCP -> I2P
|
||||
TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log, lives);
|
||||
q = new Thread(tg, conn, "BOBTCPlistener " + N);
|
||||
q = new I2PAppThread(tg, conn, "BOBTCPlistener " + N);
|
||||
q.start();
|
||||
}
|
||||
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", new Boolean(false));
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
} catch (Exception e) {
|
||||
wunlock();
|
||||
break quit;
|
||||
@ -258,9 +271,9 @@ public class MUXlisten implements Runnable {
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", new Boolean(false));
|
||||
info.add("STOPPING", new Boolean(true));
|
||||
info.add("RUNNING", new Boolean(false));
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
info.add("STOPPING", Boolean.valueOf(true));
|
||||
info.add("RUNNING", Boolean.valueOf(false));
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
@ -309,9 +322,9 @@ public class MUXlisten implements Runnable {
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", new Boolean(false));
|
||||
info.add("STOPPING", new Boolean(false));
|
||||
info.add("RUNNING", new Boolean(false));
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
info.add("STOPPING", Boolean.valueOf(false));
|
||||
info.add("RUNNING", Boolean.valueOf(false));
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package net.i2p.BOB;
|
||||
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
|
||||
/**
|
||||
@ -31,12 +30,10 @@ public class Main {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// THINK THINK THINK THINK THINK THINK
|
||||
SimpleScheduler Y1 = SimpleScheduler.getInstance();
|
||||
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
||||
|
||||
BOB.main(args);
|
||||
|
||||
Y2.stop();
|
||||
Y1.stop();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ package net.i2p.BOB;
|
||||
public class NamedDB {
|
||||
|
||||
private volatile Object[][] data;
|
||||
private volatile int index, writersWaiting, readers;
|
||||
private int index, writersWaiting, readers;
|
||||
|
||||
/**
|
||||
* make initial NULL object
|
||||
@ -31,7 +31,6 @@ public class NamedDB {
|
||||
*/
|
||||
public NamedDB() {
|
||||
this.data = new Object[1][2];
|
||||
this.index = this.writersWaiting = this.readers = 0;
|
||||
}
|
||||
|
||||
synchronized public void getReadLock() {
|
||||
@ -65,7 +64,7 @@ public class NamedDB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find objects in the array, returns it's index or throws exception
|
||||
* Find objects in the array, returns its index or throws exception
|
||||
* @param key
|
||||
* @return an objects index
|
||||
* @throws ArrayIndexOutOfBoundsException when key does not exist
|
||||
|
@ -116,7 +116,6 @@ public class TCPio implements Runnable {
|
||||
Aout.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,10 @@ import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
* Listen on TCP port and connect to I2P
|
||||
@ -31,12 +32,11 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class TCPlistener implements Runnable {
|
||||
|
||||
private NamedDB info, database;
|
||||
private Log _log;
|
||||
public I2PSocketManager socketManager;
|
||||
public I2PServerSocket serverSocket;
|
||||
private ServerSocket listener;
|
||||
private AtomicBoolean lives;
|
||||
private final NamedDB info, database;
|
||||
private final Logger _log;
|
||||
private final I2PSocketManager socketManager;
|
||||
private final ServerSocket listener;
|
||||
private final AtomicBoolean lives;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -45,7 +45,7 @@ public class TCPlistener implements Runnable {
|
||||
* @param database
|
||||
* @param _log
|
||||
*/
|
||||
TCPlistener(ServerSocket listener, I2PSocketManager S, NamedDB info, NamedDB database, Log _log, AtomicBoolean lives) {
|
||||
TCPlistener(ServerSocket listener, I2PSocketManager S, NamedDB info, NamedDB database, Logger _log, AtomicBoolean lives) {
|
||||
this.database = database;
|
||||
this.info = info;
|
||||
this._log = _log;
|
||||
@ -77,7 +77,7 @@ public class TCPlistener implements Runnable {
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
||||
Thread t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
||||
t.start();
|
||||
g = false;
|
||||
}
|
||||
|
@ -24,13 +24,14 @@ import java.net.NoRouteToHostException;
|
||||
import java.net.Socket;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
//import net.i2p.i2ptunnel.I2PTunnel;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -70,12 +71,10 @@ public class TCPtoI2P implements Runnable {
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String lnRead(InputStream in) throws IOException {
|
||||
String S;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int b;
|
||||
char c;
|
||||
|
||||
S = new String();
|
||||
|
||||
while (true) {
|
||||
b = in.read();
|
||||
if (b == 13) {
|
||||
@ -87,9 +86,9 @@ public class TCPtoI2P implements Runnable {
|
||||
break;
|
||||
}
|
||||
c = (char) (b & 0x7f); // We only care about ASCII
|
||||
S = new String(S + c);
|
||||
builder.append(c);
|
||||
}
|
||||
return S;
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,7 +100,7 @@ public class TCPtoI2P implements Runnable {
|
||||
*/
|
||||
private void Emsg(String e, OutputStream out) throws IOException {
|
||||
// Debugging System.out.println("ERROR TCPtoI2P: " + e);
|
||||
out.write("ERROR ".concat(e).getBytes());
|
||||
out.write("ERROR ".concat(e).getBytes("UTF-8"));
|
||||
out.write(13);
|
||||
out.write(10);
|
||||
out.flush();
|
||||
@ -160,8 +159,8 @@ public class TCPtoI2P implements Runnable {
|
||||
// setup to cross the streams
|
||||
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
||||
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
||||
t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||
q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||
// Fire!
|
||||
t.start();
|
||||
q.start();
|
||||
|
@ -34,15 +34,17 @@ import net.i2p.util.Log;
|
||||
* The skeletal frame is here, just needs to be finished.
|
||||
*
|
||||
* @author sponge
|
||||
* @deprecated incomplete, unused
|
||||
*/
|
||||
public class UDPIOthread implements I2PSessionListener, Runnable {
|
||||
|
||||
private NamedDB info;
|
||||
private Log _log;
|
||||
private Socket socket;
|
||||
private final NamedDB info;
|
||||
private final Log _log;
|
||||
private final Socket socket;
|
||||
private DataInputStream in;
|
||||
private DataOutputStream out;
|
||||
private I2PSession _session;
|
||||
private final I2PSession _session;
|
||||
// FIXME never set
|
||||
private Destination _peerDestination;
|
||||
private boolean up;
|
||||
|
||||
@ -58,7 +60,6 @@ public class UDPIOthread implements I2PSessionListener, Runnable {
|
||||
this._log = _log;
|
||||
this.socket = socket;
|
||||
this._session = _session;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,8 +107,10 @@ public class UDPIOthread implements I2PSessionListener, Runnable {
|
||||
// _log.debug("Message available: id = " + msgId + " size = " + size);
|
||||
try {
|
||||
byte msg[] = session.receiveMessage(msgId);
|
||||
out.write(msg);
|
||||
out.flush();
|
||||
if (msg != null) {
|
||||
out.write(msg);
|
||||
out.flush();
|
||||
}
|
||||
} catch (I2PSessionException ise) {
|
||||
up = false;
|
||||
} catch (IOException ioe) {
|
||||
|
8
apps/addressbook/.classpath
Normal file
8
apps/addressbook/.classpath
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="java/src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="/jetty/jettylib/javax.servlet.jar"/>
|
||||
<classpathentry kind="output" path="build"/>
|
||||
</classpath>
|
17
apps/addressbook/.project
Normal file
17
apps/addressbook/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>addressbook</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -7,6 +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" />
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${build}"/>
|
||||
@ -24,6 +25,18 @@
|
||||
<typefound name="depend" />
|
||||
</condition>
|
||||
<target name="depend" if="depend.available">
|
||||
<depend
|
||||
cache="../../build"
|
||||
srcdir="${src}"
|
||||
destdir="${build}" >
|
||||
<!-- Depend on classes instead of jars where available -->
|
||||
<classpath>
|
||||
<pathelement location="../../core/java/build/obj" />
|
||||
</classpath>
|
||||
</depend>
|
||||
</target>
|
||||
|
||||
<target name="dependServlet" if="depend.available">
|
||||
<depend
|
||||
cache="../../build"
|
||||
srcdir="${src}"
|
||||
@ -37,9 +50,22 @@
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init, depend">
|
||||
<javac debug="true" deprecation="on" source="1.5" target="1.5"
|
||||
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||
includeAntRuntime="false"
|
||||
srcdir="${src}" destdir="${build}">
|
||||
srcdir="${src}" destdir="${build}"
|
||||
excludes="net/i2p/addressbook/Servlet.java">
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
<classpath>
|
||||
<pathelement location="../../core/java/build/i2p.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="compileServlet" depends="init, dependServlet, compile">
|
||||
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||
includeAntRuntime="false"
|
||||
srcdir="${src}" destdir="${build}"
|
||||
includes="net/i2p/addressbook/Servlet.java">
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
<classpath>
|
||||
<pathelement location="../../core/java/build/i2p.jar" />
|
||||
@ -48,11 +74,11 @@
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<!-- unused for now, as we oddly ship addressbook as a .war -->
|
||||
<!-- unused for now (except for Android), as we oddly ship addressbook as a .war -->
|
||||
<target name="jar" depends="compile, changes">
|
||||
<jar basedir="${build}" destfile="${dist}/${jar}">
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes" value="" />
|
||||
<jar basedir="${build}" destfile="${dist}/${jar}">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="addressbook.Daemon"/>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
@ -64,7 +90,7 @@
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="war" depends="compile, changes, warUpToDate" unless="war.uptodate">
|
||||
<target name="war" depends="compileServlet, changes, warUpToDate" unless="war.uptodate">
|
||||
<mkdir dir="${dist}/tmp"/>
|
||||
<mkdir dir="${dist}/tmp/WEB-INF"/>
|
||||
<mkdir dir="${dist}/tmp/WEB-INF/classes"/>
|
||||
|
@ -27,6 +27,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.EepGet;
|
||||
@ -49,6 +50,26 @@ class AddressBook {
|
||||
private boolean modified;
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final int MIN_DEST_LENGTH = 516;
|
||||
private static final int MAX_DEST_LENGTH = MIN_DEST_LENGTH + 100; // longer than any known cert type for now
|
||||
|
||||
/**
|
||||
* 5-67 chars lower/upper case
|
||||
*/
|
||||
private static final Pattern HOST_PATTERN =
|
||||
Pattern.compile("^[0-9a-zA-Z\\.-]{5,67}$");
|
||||
|
||||
/**
|
||||
* 52 chars lower/upper case
|
||||
* Always ends in 'a' or 'q'
|
||||
*/
|
||||
private static final Pattern B32_PATTERN =
|
||||
Pattern.compile("^[2-7a-zA-Z]{51}[aAqQ]$");
|
||||
|
||||
/** not a complete qualification, just a quick check */
|
||||
private static final Pattern B64_PATTERN =
|
||||
Pattern.compile("^[0-9a-zA-Z~-]{" + MIN_DEST_LENGTH + ',' + MAX_DEST_LENGTH + "}={0,2}$");
|
||||
|
||||
/**
|
||||
* Construct an AddressBook from the contents of the Map addresses.
|
||||
*
|
||||
@ -120,11 +141,11 @@ class AddressBook {
|
||||
subscription.setLastFetched(I2PAppContext.getGlobalContext().clock().now());
|
||||
subf = tmp;
|
||||
} else {
|
||||
a = Collections.EMPTY_MAP;
|
||||
a = Collections.emptyMap();
|
||||
tmp.delete();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
a = Collections.EMPTY_MAP;
|
||||
a = Collections.emptyMap();
|
||||
}
|
||||
this.addresses = a;
|
||||
this.subFile = subf;
|
||||
@ -148,7 +169,7 @@ class AddressBook {
|
||||
try {
|
||||
a = ConfigParser.parse(file);
|
||||
} catch (IOException exp) {
|
||||
a = new HashMap();
|
||||
a = new HashMap<String, String>();
|
||||
}
|
||||
this.addresses = a;
|
||||
this.subFile = null;
|
||||
@ -159,8 +180,13 @@ class AddressBook {
|
||||
* @since 0.8.7
|
||||
*/
|
||||
public Iterator<Map.Entry<String, String>> iterator() {
|
||||
if (this.subFile != null)
|
||||
return new ConfigIterator(this.subFile);
|
||||
if (this.subFile != null) {
|
||||
try {
|
||||
return new ConfigIterator(this.subFile);
|
||||
} catch (IOException ioe) {
|
||||
return new ConfigIterator();
|
||||
}
|
||||
}
|
||||
return this.addresses.entrySet().iterator();
|
||||
}
|
||||
|
||||
@ -201,9 +227,6 @@ class AddressBook {
|
||||
return "Map containing " + this.addresses.size() + " entries";
|
||||
}
|
||||
|
||||
private static final int MIN_DEST_LENGTH = 516;
|
||||
private static final int MAX_DEST_LENGTH = MIN_DEST_LENGTH + 100; // longer than any known cert type for now
|
||||
|
||||
/**
|
||||
* Do basic validation of the hostname
|
||||
* hostname was already converted to lower case by ConfigParser.parse()
|
||||
@ -220,9 +243,10 @@ class AddressBook {
|
||||
host.indexOf("..") < 0 &&
|
||||
// IDN - basic check, not complete validation
|
||||
(host.indexOf("--") < 0 || host.startsWith("xn--") || host.indexOf(".xn--") > 0) &&
|
||||
host.replaceAll("[a-z0-9.-]", "").length() == 0 &&
|
||||
HOST_PATTERN.matcher(host).matches() &&
|
||||
// Base32 spoofing (52chars.i2p)
|
||||
(! (host.length() == 56 && host.substring(0,52).replaceAll("[a-z2-7]", "").length() == 0)) &&
|
||||
// We didn't do it this way, we use a .b32.i2p suffix, but let's prohibit it anyway
|
||||
(! (host.length() == 56 && B32_PATTERN.matcher(host.substring(0,52)).matches())) &&
|
||||
// ... or maybe we do Base32 this way ...
|
||||
(! host.equals("b32.i2p")) &&
|
||||
(! host.endsWith(".b32.i2p")) &&
|
||||
@ -246,7 +270,7 @@ class AddressBook {
|
||||
(dest.length() > MIN_DEST_LENGTH && dest.length() <= MAX_DEST_LENGTH)) &&
|
||||
// B64 comes in groups of 2, 3, or 4 chars, but never 1
|
||||
((dest.length() % 4) != 1) &&
|
||||
dest.replaceAll("[a-zA-Z0-9~-]", "").length() == 0
|
||||
B64_PATTERN.matcher(dest).matches()
|
||||
;
|
||||
}
|
||||
|
||||
@ -260,7 +284,7 @@ class AddressBook {
|
||||
* An AddressBook to merge with.
|
||||
* @param overwrite True to overwrite
|
||||
* @param log
|
||||
* The log to write messages about new addresses or conflicts to.
|
||||
* The log to write messages about new addresses or conflicts to. May be null.
|
||||
*
|
||||
* @throws IllegalStateException if this was created with the Subscription constructor.
|
||||
*/
|
||||
@ -332,4 +356,27 @@ class AddressBook {
|
||||
protected void finalize() {
|
||||
delete();
|
||||
}
|
||||
|
||||
/****
|
||||
public static void main(String[] args) {
|
||||
String[] tests = { "foo.i2p",
|
||||
"3bnipzzu67cdq2rcygyxz52xhvy6ylokn4zfrk36ywn6pixmaoza.b32.i2p",
|
||||
"9rhEy4dT9fMlcSOhDzfWRxCV2aen4Zp4eSthOf5f9gVKMa4PtQJ-wEzm2KEYeDXkbM6wEDvMQ6ou4LIniSE6bSAwy7fokiXk5oabels-sJmftnQWRbZyyXEAsLc3gpJJvp9km7kDyZ0z0YGL5tf3S~OaWdptB5tSBOAOjm6ramcYZMWhyUqm~xSL1JyXUqWEHRYwhoDJNL6-L516VpDYVigMBpIwskjeFGcqK8BqWAe0bRwxIiFTPN6Ck8SDzQvS1l1Yj-zfzg3X3gOknzwR8nrHUkjsWtEB6nhbOr8AR21C9Hs0a7MUJvSe2NOuBoNTrtxT76jDruI78JcG5r~WKl6M12yM-SqeBNE9hQn2QCHeHAKju7FdRCbqaZ99IwyjfwvZbkiYYQVN1xlUuGaXrj98XDzK7GORYdH-PrVGfEbMXQ40KLHUWHz8w4tQXAOQrCHEichod0RIzuuxo3XltCWKrf1xGZhkAo9bk2qXi6digCijvYNaKmQdXZYWW~RtAAAA",
|
||||
"6IZTYacjlXjSAxu-uXEO5oGsj-f4tfePHEvGjs5pu-AMXMwD7-xFdi8kdobDMJp9yRAl96U7yLl~0t9zHeqqYmNeZnDSkTmAcSC2PT45ZJDXBobKi1~a77zuqfPwnzEatYfW3GL1JQAEkAmiwNJoG7ThTZ3zT7W9ekVJpHi9mivpTbaI~rALLfuAg~Mvr60nntZHjqhEZuiU4dTXrmc5nykl~UaMnBdwHL4jKmoN5CotqHyLYZfp74fdD-Oq4SkhuBhU8wkBIM3lz3Ul1o6-s0lNUMdYJq1CyxnyP7jeekdfAlSx4P4sU4M0dPaYvPdOFWPWwBuEh0pCs5Mj01B2xeEBhpV~xSLn6ru5Vq98TrmaR33KHxd76OYYFsWwzVbBuMVSd800XpBghGFucGw01YHYsPh3Afb01sXbf8Nb1bkxCy~DsrmoH4Ww3bpx66JhRTWvg5al3oWlCX51CnJUqaaK~dPL-pBvAyLKIA5aYvl8ca66jtA7AFDxsOb2texBBQAEAAcAAA==",
|
||||
"te9Ky7XvVcLLr5vQqvfmOasg915P3-ddP3iDqpMMk7v5ufFKobLAX~1k-E4WVsJVlkYvkHVOjxix-uT1IdewKmLd81s5wZtz0GQ3ZC6p0C3S2cOxz7kQqf7QYSR0BrhZC~2du3-GdQO9TqNmsnHrah5lOZf0LN2JFEFPqg8ZB5JNm3JjJeSqePBRk3zAUogNaNK3voB1MVI0ZROKopXAJM4XMERNqI8tIH4ngGtV41SEJJ5pUFrrTx~EiUPqmSEaEA6UDYZiqd23ZlewZ31ExXQj97zvkuhKCoS9A9MNkzZejJhP-TEXWF8~KHur9f51H--EhwZ42Aj69-3GuNjsMdTwglG5zyIfhd2OspxJrXzCPqIV2sXn80IbPgwxHu0CKIJ6X43B5vTyVu87QDI13MIRNGWNZY5KmM5pilGP7jPkOs4xQDo4NHzpuJR5igjWgJIBPU6fI9Pzq~BMzjLiZOMp8xNWey1zKC96L0eX4of1MG~oUvq0qmIHGNa1TlUwBQAEAAEAAA==",
|
||||
"(*&(*&(*&(*",
|
||||
"9rhEy4dT9fMlcSOhDzfWRxCV2aen4Zp4eSthOf5f9gVKMa4PtQJ-wEzm2KEYeDXkbM6wEDvMQ6ou4LIniSE6bSAwy7fokiXk5oabels-sJmftnQWRbZyyXEAsLc3gpJJvp9km7kDyZ0z0YGL5tf3S~OaWdptB5tSBOAOjm6ramcYZMWhyUqm~xSL1JyXUqWEHRYwhoDJNL6-L516VpDYVigMBpIwskjeFGcqK8BqWAe0bRwxIiFTPN6Ck8SDzQvS1l1Yj-zfzg3X3gOknzwR8nrHUkjsWtEB6nhbOr8AR21C9Hs0a7MUJvSe2NOuBoNTrtxT76jDruI78JcG5r~WKl6M12yM-SqeBNE9hQn2QCHeHAKju7FdRCbqaZ99IwyjfwvZbkiYYQVN1xlUuGaXrj98XDzK7GORYdH-PrVGfEbMXQ40KLHUWHz8w4tQXAOQrCHEichod0RIzuuxo3XltCWKrf1xGZhkAo9bk2qXi6digCijvYNaKmQdXZYWW~RtAAA",
|
||||
"6IZTYacjlXjSAxu-uXEO5oGsj-f4tfePHEvGjs5pu-AMXMwD7-xFdi8kdobDMJp9yRAl96U7yLl~0t9zHeqqYmNeZnDSkTmAcSC2PT45ZJDXBobKi1~a77zuqfPwnzEatYfW3GL1JQAEkAmiwNJoG7ThTZ3zT7W9ekVJpHi9mivpTbaI~rALLfuAg~Mvr60nntZHjqhEZuiU4dTXrmc5nykl~UaMnBdwHL4jKmoN5CotqHyLYZfp74fdD-Oq4SkhuBhU8wkBIM3lz3Ul1o6-s0lNUMdYJq1CyxnyP7jeekdfAlSx4P4sU4M0dPaYvPdOFWPWwBuEh0pCs5Mj01B2xeEBhpV~xSLn6ru5Vq98TrmaR33KHxd76OYYFsWwzVbBuMVSd800XpBghGFucGw01YHYsPh3Afb01sXbf8Nb1bkxCy~DsrmoH4Ww3bpx66JhRTWvg5al3oWlCX51CnJUqaaK~dPL-pBvAyLKIA5aYvl8ca66jtA7AFDxsOb2texBBQAEAAcAAA===",
|
||||
"!e9Ky7XvVcLLr5vQqvfmOasg915P3-ddP3iDqpMMk7v5ufFKobLAX~1k-E4WVsJVlkYvkHVOjxix-uT1IdewKmLd81s5wZtz0GQ3ZC6p0C3S2cOxz7kQqf7QYSR0BrhZC~2du3-GdQO9TqNmsnHrah5lOZf0LN2JFEFPqg8ZB5JNm3JjJeSqePBRk3zAUogNaNK3voB1MVI0ZROKopXAJM4XMERNqI8tIH4ngGtV41SEJJ5pUFrrTx~EiUPqmSEaEA6UDYZiqd23ZlewZ31ExXQj97zvkuhKCoS9A9MNkzZejJhP-TEXWF8~KHur9f51H--EhwZ42Aj69-3GuNjsMdTwglG5zyIfhd2OspxJrXzCPqIV2sXn80IbPgwxHu0CKIJ6X43B5vTyVu87QDI13MIRNGWNZY5KmM5pilGP7jPkOs4xQDo4NHzpuJR5igjWgJIBPU6fI9Pzq~BMzjLiZOMp8xNWey1zKC96L0eX4of1MG~oUvq0qmIHGNa1TlUwBQAEAAEAAA==",
|
||||
"x"
|
||||
};
|
||||
for (String s : tests) {
|
||||
test(s);
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(String s) {
|
||||
System.out.println(s + " valid host? " + isValidKey(s) + " valid dest? " + isValidDest(s));
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
package net.i2p.addressbook;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -31,6 +32,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
* A class to iterate through a hosts.txt or config file without
|
||||
* reading the whole thing into memory.
|
||||
@ -41,7 +44,7 @@ import java.util.NoSuchElementException;
|
||||
*
|
||||
* @since 0.8.7
|
||||
*/
|
||||
class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
||||
class ConfigIterator implements Iterator<Map.Entry<String, String>>, Closeable {
|
||||
|
||||
private BufferedReader input;
|
||||
private ConfigEntry next;
|
||||
@ -54,11 +57,9 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
||||
/**
|
||||
* An iterator over the key/value pairs in the file.
|
||||
*/
|
||||
public ConfigIterator(File file) {
|
||||
try {
|
||||
public ConfigIterator(File file) throws IOException {
|
||||
FileInputStream fileStream = new FileInputStream(file);
|
||||
input = new BufferedReader(new InputStreamReader(fileStream));
|
||||
} catch (IOException ioe) {}
|
||||
input = new BufferedReader(new InputStreamReader(fileStream, "UTF-8"));
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
@ -70,7 +71,7 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
||||
String inputLine = input.readLine();
|
||||
while (inputLine != null) {
|
||||
inputLine = ConfigParser.stripComments(inputLine);
|
||||
String[] splitLine = inputLine.split("=");
|
||||
String[] splitLine = DataHelper.split(inputLine, "=");
|
||||
if (splitLine.length == 2) {
|
||||
next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
|
||||
return true;
|
||||
@ -138,7 +139,8 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
@SuppressWarnings("unchecked")
|
||||
Map.Entry<Object, Object> e = (Map.Entry<Object, Object>) o;
|
||||
return key.equals(e.getKey()) && value.equals(e.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.SecureFile;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.SystemVersion;
|
||||
@ -64,10 +65,11 @@ class ConfigParser {
|
||||
if (inputLine.startsWith(";")) {
|
||||
return "";
|
||||
}
|
||||
if (inputLine.split("#").length > 0) {
|
||||
return inputLine.split("#")[0];
|
||||
int hash = inputLine.indexOf('#');
|
||||
if (hash >= 0) {
|
||||
return inputLine.substring(0, hash);
|
||||
} else {
|
||||
return "";
|
||||
return inputLine;
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,12 +89,12 @@ class ConfigParser {
|
||||
*
|
||||
*/
|
||||
public static Map<String, String> parse(BufferedReader input) throws IOException {
|
||||
Map<String, String> result = new HashMap();
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
String inputLine;
|
||||
inputLine = input.readLine();
|
||||
while (inputLine != null) {
|
||||
inputLine = ConfigParser.stripComments(inputLine);
|
||||
String[] splitLine = inputLine.split("=");
|
||||
inputLine = stripComments(inputLine);
|
||||
String[] splitLine = DataHelper.split(inputLine, "=");
|
||||
if (splitLine.length == 2) {
|
||||
result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
|
||||
}
|
||||
@ -115,8 +117,8 @@ class ConfigParser {
|
||||
public static Map<String, String> parse(File file) throws IOException {
|
||||
FileInputStream fileStream = new FileInputStream(file);
|
||||
BufferedReader input = new BufferedReader(new InputStreamReader(
|
||||
fileStream));
|
||||
Map<String, String> rv = ConfigParser.parse(input);
|
||||
fileStream, "UTF-8"));
|
||||
Map<String, String> rv = parse(input);
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException ioe) {}
|
||||
@ -136,7 +138,7 @@ class ConfigParser {
|
||||
public static Map<String, String> parse(String string) throws IOException {
|
||||
StringReader stringReader = new StringReader(string);
|
||||
BufferedReader input = new BufferedReader(stringReader);
|
||||
return ConfigParser.parse(input);
|
||||
return parse(input);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,7 +155,7 @@ class ConfigParser {
|
||||
public static Map<String, String> parse(File file, Map<String, String> map) {
|
||||
Map<String, String> result;
|
||||
try {
|
||||
result = ConfigParser.parse(file);
|
||||
result = parse(file);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
if (!result.containsKey(entry.getKey()))
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
@ -161,7 +163,7 @@ class ConfigParser {
|
||||
} catch (IOException exp) {
|
||||
result = map;
|
||||
try {
|
||||
ConfigParser.write(result, file);
|
||||
write(result, file);
|
||||
} catch (IOException exp2) {
|
||||
}
|
||||
}
|
||||
@ -179,10 +181,10 @@ class ConfigParser {
|
||||
*/
|
||||
public static List<String> parseSubscriptions(BufferedReader input)
|
||||
throws IOException {
|
||||
List<String> result = new LinkedList();
|
||||
List<String> result = new LinkedList<String>();
|
||||
String inputLine = input.readLine();
|
||||
while (inputLine != null) {
|
||||
inputLine = ConfigParser.stripComments(inputLine).trim();
|
||||
inputLine = stripComments(inputLine).trim();
|
||||
if (inputLine.length() > 0) {
|
||||
result.add(inputLine);
|
||||
}
|
||||
@ -204,8 +206,8 @@ class ConfigParser {
|
||||
public static List<String> parseSubscriptions(File file) throws IOException {
|
||||
FileInputStream fileStream = new FileInputStream(file);
|
||||
BufferedReader input = new BufferedReader(new InputStreamReader(
|
||||
fileStream));
|
||||
List<String> rv = ConfigParser.parseSubscriptions(input);
|
||||
fileStream, "UTF-8"));
|
||||
List<String> rv = parseSubscriptions(input);
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException ioe) {}
|
||||
@ -224,7 +226,7 @@ class ConfigParser {
|
||||
public static List<String> parseSubscriptions(String string) throws IOException {
|
||||
StringReader stringReader = new StringReader(string);
|
||||
BufferedReader input = new BufferedReader(stringReader);
|
||||
return ConfigParser.parseSubscriptions(input);
|
||||
return parseSubscriptions(input);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,18 +236,30 @@ class ConfigParser {
|
||||
*
|
||||
* @param file
|
||||
* A File to attempt to parse.
|
||||
* @param list list of files to parse
|
||||
* @param list The default subscriptions to be saved and returned if the file cannot be read
|
||||
* @return A List consisting of one element for each line in file, or if
|
||||
* file cannot be read, list.
|
||||
*/
|
||||
public static List<String> parseSubscriptions(File file, List<String> list) {
|
||||
List<String> result;
|
||||
try {
|
||||
result = ConfigParser.parseSubscriptions(file);
|
||||
result = parseSubscriptions(file);
|
||||
// Fix up files that contain the old default
|
||||
// which was changed in 0.9.11
|
||||
if (result.remove(Daemon.OLD_DEFAULT_SUB)) {
|
||||
for (String sub : list) {
|
||||
if (!result.contains(sub))
|
||||
result.add(sub);
|
||||
}
|
||||
try {
|
||||
writeSubscriptions(result, file);
|
||||
// TODO log
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
} catch (IOException exp) {
|
||||
result = list;
|
||||
try {
|
||||
ConfigParser.writeSubscriptions(result, file);
|
||||
writeSubscriptions(result, file);
|
||||
} catch (IOException exp2) {
|
||||
}
|
||||
}
|
||||
@ -289,8 +303,7 @@ class ConfigParser {
|
||||
boolean success = false;
|
||||
if (!isWindows) {
|
||||
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
|
||||
ConfigParser
|
||||
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
||||
write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
||||
success = tmp.renameTo(file);
|
||||
if (!success) {
|
||||
tmp.delete();
|
||||
@ -299,8 +312,7 @@ class ConfigParser {
|
||||
}
|
||||
if (!success) {
|
||||
// hmm, that didn't work, try it the old way
|
||||
ConfigParser
|
||||
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
||||
write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,7 +349,7 @@ class ConfigParser {
|
||||
*/
|
||||
public static void writeSubscriptions(List<String> list, File file)
|
||||
throws IOException {
|
||||
ConfigParser.writeSubscriptions(list, new BufferedWriter(
|
||||
writeSubscriptions(list, new BufferedWriter(
|
||||
new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ import net.i2p.client.naming.SingleFileNamingService;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Main class of addressbook. Performs updates, and runs the main loop.
|
||||
@ -49,6 +50,9 @@ public class Daemon {
|
||||
private static final Daemon _instance = new Daemon();
|
||||
private volatile boolean _running;
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String DEFAULT_SUB = "http://i2p-projekt.i2p/hosts.txt";
|
||||
/** @since 0.9.12 */
|
||||
static final String OLD_DEFAULT_SUB = "http://www.i2p2.i2p/hosts.txt";
|
||||
|
||||
/**
|
||||
* Update the router and published address books using remote data from the
|
||||
@ -168,7 +172,7 @@ public class Daemon {
|
||||
if (publishedNS == null)
|
||||
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||
success = publishedNS.putIfAbsent(key, dest);
|
||||
if (!success) {
|
||||
if (log != null && !success) {
|
||||
try {
|
||||
log.append("Save to published address book " + published.getCanonicalPath() + " failed for new key " + key);
|
||||
} catch (IOException ioe) {}
|
||||
@ -250,14 +254,14 @@ public class Daemon {
|
||||
}
|
||||
delay *= 60 * 60 * 1000;
|
||||
|
||||
List<String> defaultSubs = new LinkedList();
|
||||
List<String> defaultSubs = new LinkedList<String>();
|
||||
// defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
|
||||
defaultSubs.add("http://www.i2p2.i2p/hosts.txt");
|
||||
defaultSubs.add(DEFAULT_SUB);
|
||||
|
||||
SubscriptionList subscriptions = new SubscriptionList(subscriptionFile,
|
||||
etagsFile, lastModifiedFile, lastFetchedFile, delay, defaultSubs, settings
|
||||
.get("proxy_host"), Integer.parseInt(settings.get("proxy_port")));
|
||||
Log log = new Log(logFile);
|
||||
Log log = SystemVersion.isAndroid() ? null : new Log(logFile);
|
||||
|
||||
// If false, add hosts via naming service; if true, write hosts.txt file directly
|
||||
// Default false
|
||||
@ -330,7 +334,7 @@ public class Daemon {
|
||||
homeFile = new SecureDirectory(System.getProperty("user.dir"));
|
||||
}
|
||||
|
||||
Map<String, String> defaultSettings = new HashMap();
|
||||
Map<String, String> defaultSettings = new HashMap<String, String>();
|
||||
defaultSettings.put("proxy_host", "127.0.0.1");
|
||||
defaultSettings.put("proxy_port", "4444");
|
||||
defaultSettings.put("master_addressbook", "../userhosts.txt");
|
||||
|
@ -25,6 +25,7 @@ import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.NamingServiceUpdater;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
* A thread that waits five minutes, then runs the addressbook daemon.
|
||||
@ -32,7 +33,7 @@ import net.i2p.client.naming.NamingServiceUpdater;
|
||||
* @author Ragnarok
|
||||
*
|
||||
*/
|
||||
public class DaemonThread extends Thread implements NamingServiceUpdater {
|
||||
public class DaemonThread extends I2PAppThread implements NamingServiceUpdater {
|
||||
|
||||
private String[] args;
|
||||
|
||||
|
@ -23,8 +23,9 @@ package net.i2p.addressbook;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@ -56,8 +57,8 @@ class Log {
|
||||
public void append(String entry) {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(this.file,
|
||||
true));
|
||||
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.file,
|
||||
true), "UTF-8"));
|
||||
String timestamp = new Date().toString();
|
||||
bw.write(timestamp + " -- " + entry);
|
||||
bw.newLine();
|
||||
|
@ -41,7 +41,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
*
|
||||
*/
|
||||
public class Servlet extends HttpServlet {
|
||||
private DaemonThread thread;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private transient DaemonThread thread;
|
||||
//private String nonce;
|
||||
//private static final String PROP_NONCE = "addressbook.nonce";
|
||||
|
||||
|
@ -26,6 +26,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.PortMapper;
|
||||
|
||||
/**
|
||||
* An iterator over the subscriptions in a SubscriptionList. Note that this iterator
|
||||
@ -69,11 +70,14 @@ class SubscriptionIterator implements Iterator<AddressBook> {
|
||||
* Yes, the EepGet fetch() is done in here in next().
|
||||
*
|
||||
* see java.util.Iterator#next()
|
||||
* @return an AddressBook (empty if the minimum delay has not been met)
|
||||
* @return non-null AddressBook (empty if the minimum delay has not been met,
|
||||
* or there is no proxy tunnel, or the fetch otherwise fails)
|
||||
*/
|
||||
public AddressBook next() {
|
||||
Subscription sub = this.subIterator.next();
|
||||
if (sub.getLastFetched() + this.delay < I2PAppContext.getGlobalContext().clock().now()) {
|
||||
if (sub.getLastFetched() + this.delay < I2PAppContext.getGlobalContext().clock().now() &&
|
||||
I2PAppContext.getGlobalContext().portMapper().getPort(PortMapper.SVC_HTTP_PROXY) >= 0 &&
|
||||
!I2PAppContext.getGlobalContext().getBooleanProperty("i2p.vmCommSystem")) {
|
||||
//System.err.println("Fetching addressbook from " + sub.getLocation());
|
||||
return new AddressBook(sub, this.proxyHost, this.proxyPort);
|
||||
} else {
|
||||
@ -81,7 +85,7 @@ class SubscriptionIterator implements Iterator<AddressBook> {
|
||||
// DataHelper.formatDuration(I2PAppContext.getGlobalContext().clock().now() - sub.getLastFetched()) +
|
||||
// " ago but the minimum delay is " +
|
||||
// DataHelper.formatDuration(this.delay));
|
||||
return new AddressBook(Collections.EMPTY_MAP);
|
||||
return new AddressBook(Collections.<String, String> emptyMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ class SubscriptionList {
|
||||
public SubscriptionList(File locationsFile, File etagsFile,
|
||||
File lastModifiedFile, File lastFetchedFile, long delay, List<String> defaultSubs, String proxyHost,
|
||||
int proxyPort) {
|
||||
this.subscriptions = new LinkedList();
|
||||
this.subscriptions = new LinkedList<Subscription>();
|
||||
this.etagsFile = etagsFile;
|
||||
this.lastModifiedFile = lastModifiedFile;
|
||||
this.lastFetchedFile = lastFetchedFile;
|
||||
@ -84,17 +84,17 @@ class SubscriptionList {
|
||||
try {
|
||||
etags = ConfigParser.parse(etagsFile);
|
||||
} catch (IOException exp) {
|
||||
etags = new HashMap();
|
||||
etags = new HashMap<String, String>();
|
||||
}
|
||||
try {
|
||||
lastModified = ConfigParser.parse(lastModifiedFile);
|
||||
} catch (IOException exp) {
|
||||
lastModified = new HashMap();
|
||||
lastModified = new HashMap<String, String>();
|
||||
}
|
||||
try {
|
||||
lastFetched = ConfigParser.parse(lastFetchedFile);
|
||||
} catch (IOException exp) {
|
||||
lastFetched = new HashMap();
|
||||
lastFetched = new HashMap<String, String>();
|
||||
}
|
||||
for (String location : locations) {
|
||||
this.subscriptions.add(new Subscription(location, etags.get(location),
|
||||
@ -121,9 +121,9 @@ class SubscriptionList {
|
||||
* won't be read back correctly; the '=' should be escaped.
|
||||
*/
|
||||
public void write() {
|
||||
Map<String, String> etags = new HashMap();
|
||||
Map<String, String> lastModified = new HashMap();
|
||||
Map<String, String> lastFetched = new HashMap();
|
||||
Map<String, String> etags = new HashMap<String, String>();
|
||||
Map<String, String> lastModified = new HashMap<String, String>();
|
||||
Map<String, String> lastFetched = new HashMap<String, String>();
|
||||
for (Subscription sub : this.subscriptions) {
|
||||
if (sub.getEtag() != null) {
|
||||
etags.put(sub.getLocation(), sub.getEtag());
|
||||
|
11
apps/addressbook/java/src/net/i2p/addressbook/package.html
Normal file
11
apps/addressbook/java/src/net/i2p/addressbook/package.html
Normal file
@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The addressbook application, which fetches hosts.txt files from subscription URLS via
|
||||
HTTP and adds new hosts to the local database.
|
||||
While implemented as a webapp, this application contains no user interface.
|
||||
May also be packaged as a jar, as is done for Android.
|
||||
The webapp named 'addressbook' in the console is actually SusiDNS.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -4,6 +4,15 @@
|
||||
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
|
||||
|
||||
<web-app>
|
||||
<filter>
|
||||
<filter-name>XSSFilter</filter-name>
|
||||
<filter-class>net.i2p.servlet.filters.XSSFilter</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>XSSFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>addressbook</servlet-name>
|
||||
<servlet-class>net.i2p.addressbook.Servlet</servlet-class>
|
||||
@ -19,4 +28,11 @@
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- this webapp doesn't actually use sessions or cookies -->
|
||||
<session-config>
|
||||
<session-timeout>30</session-timeout>
|
||||
<cookie-config>
|
||||
<http-only>true</http-only>
|
||||
</cookie-config>
|
||||
</session-config>
|
||||
</web-app>
|
||||
|
@ -11,6 +11,7 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.DataHelper
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.I2PThread;
|
||||
@ -47,7 +48,7 @@ class AdminRunner implements Runnable {
|
||||
reply(out, "this is not a website");
|
||||
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
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));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
@ -61,7 +62,7 @@ class AdminRunner implements Runnable {
|
||||
reply(out, shutdown(command));
|
||||
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
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));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
@ -80,7 +81,7 @@ class AdminRunner implements Runnable {
|
||||
reply.append("Content-type: text/html\n\n");
|
||||
reply.append(content);
|
||||
try {
|
||||
out.write(reply.toString().getBytes());
|
||||
out.write(DataHelper.getASCII(reply.toString()));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@ -97,7 +98,7 @@ class AdminRunner implements Runnable {
|
||||
reply.append("Content-type: text/plain\n\n");
|
||||
reply.append(content);
|
||||
try {
|
||||
out.write(reply.toString().getBytes());
|
||||
out.write(DataHelper.getASCII(reply.toString()));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
99
apps/apparmor/home.i2p.i2prouter
Normal file
99
apps/apparmor/home.i2p.i2prouter
Normal file
@ -0,0 +1,99 @@
|
||||
#Last Modified: Sun Dec 06 12:30:32 2015
|
||||
# vim:syntax=apparmor et ts=8 sw=4
|
||||
|
||||
#include <tunables/global>
|
||||
|
||||
$INSTALL_PATH/{i2prouter,runplain.sh} flags=(complain) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/fonts>
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/ssl_certs>
|
||||
|
||||
capability sys_ptrace,
|
||||
network inet stream,
|
||||
network inet6 stream,
|
||||
|
||||
$INSTALL_PATH/ r,
|
||||
$INSTALL_PATH/{i2psvc,wrapper} rmix,
|
||||
owner $INSTALL_PATH/** rwkm,
|
||||
|
||||
# Needed for Java
|
||||
owner @{PROC} r,
|
||||
owner @{PROC}/[0-9]*/ r,
|
||||
owner @{PROC}/[0-9]*/status r,
|
||||
owner @{PROC}/[0-9]*/stat r,
|
||||
owner @{PROC}/[0-9]*/cmdline r,
|
||||
@{PROC}/uptime r,
|
||||
@{PROC}/sys/kernel/pid_max r,
|
||||
/sys/devices/system/cpu/ r,
|
||||
/sys/devices/system/cpu/** r,
|
||||
|
||||
/dev/random r,
|
||||
/dev/urandom r,
|
||||
|
||||
@{PROC}/1/comm r,
|
||||
|
||||
/etc/ssl/certs/java/** r,
|
||||
/etc/timezone r,
|
||||
/usr/share/javazi/** r,
|
||||
|
||||
# Debian
|
||||
/etc/java-{6,7,8}-openjdk/** r,
|
||||
/usr/lib/jvm/default-java/jre/bin/java rix,
|
||||
|
||||
# Debian, Ubuntu, openSUSE
|
||||
/usr/lib{,32,64}/jvm/java-*-openjdk-*/jre/bin/java rix,
|
||||
/usr/lib{,32,64}/jvm/java-*-openjdk-*/jre/bin/keytool rix,
|
||||
|
||||
# Raspbian
|
||||
/usr/lib/jvm/jdk-*-oracle-*/jre/bin/java rix,
|
||||
/usr/lib/jvm/jdk-*-oracle-*/jre/bin/keytool rix,
|
||||
|
||||
|
||||
# Fonts are needed for I2P's graphs
|
||||
/usr/share/java/java-atk-wrapper.jar r,
|
||||
|
||||
# Used by some plugins
|
||||
/usr/share/java/eclipse-ecj-*.jar r,
|
||||
|
||||
/{,var/}tmp/ rwm,
|
||||
owner /{,var/}tmp/** rwkm,
|
||||
|
||||
/{,usr/}bin/{,b,d}ash rix,
|
||||
/{,usr/}bin/cat rix,
|
||||
/{,usr/}bin/cut rix,
|
||||
/{,usr/}bin/dirname rix,
|
||||
/{,usr/}bin/expr rix,
|
||||
/{,usr/}bin/{,g,m}awk rix,
|
||||
/{,usr/}bin/grep rix,
|
||||
/{,usr/}bin/id rix,
|
||||
/{,usr/}bin/ldd rix,
|
||||
/{,usr/}bin/ls rix,
|
||||
/{,usr/}bin/mkdir rix,
|
||||
/{,usr/}bin/nohup rix,
|
||||
/{,usr/}bin/ps rix,
|
||||
/{,usr/}bin/rm rix,
|
||||
/{,usr/}bin/sed rix,
|
||||
/{,usr/}bin/sleep rix,
|
||||
/{,usr/}bin/tail rix,
|
||||
/{,usr/}bin/tr rix,
|
||||
/{,usr/}bin/uname rix,
|
||||
/{,usr/}bin/which rix,
|
||||
|
||||
@{HOME}/.java/fonts/** r,
|
||||
owner @{HOME}/.i2p/ rw,
|
||||
owner @{HOME}/.i2p/** rwk,
|
||||
|
||||
# Prevent spamming the logs
|
||||
deny owner @{HOME}/.java/ wk,
|
||||
deny @{HOME}/.fontconfig/ wk,
|
||||
deny @{HOME}/.java/fonts/** w,
|
||||
deny /dev/tty rw,
|
||||
deny /dev/pts/[0-9]* rw,
|
||||
deny @{PROC}/[0-9]*/fd/ r,
|
||||
deny /usr/local/share/fonts/ r,
|
||||
deny /var/cache/fontconfig/ wk,
|
||||
# Used by some versions of the Tanuki wrapper but never used by I2P
|
||||
deny /usr/share/java/hamcrest*.jar r,
|
||||
deny /usr/share/java/junit*.jar r,
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_router"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
|
||||
<classpathentry kind="lib" path="/lib/wrapper/all/wrapper.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/installer"/>
|
||||
<classpathentry kind="output" path="build"/>
|
||||
</classpath>
|
||||
|
@ -7,12 +7,13 @@
|
||||
<property name="jar" value="desktopgui.jar"/>
|
||||
<property name="resources" value="resources"/>
|
||||
<property name="javadoc" value="javadoc"/>
|
||||
<property name="javac.compilerargs" value=""/>
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<condition property="no.bundle">
|
||||
<isfalse value="${require.gettext}" />
|
||||
</condition>
|
||||
<property name="javac.compilerargs" value=""/>
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${build}"/>
|
||||
@ -27,7 +28,7 @@
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<javac debug="true" deprecation="on" source="1.5" target="1.5"
|
||||
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||
includeAntRuntime="false"
|
||||
srcdir="${src}" destdir="${build}">
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
@ -44,6 +45,7 @@
|
||||
|
||||
<target name="bundle" unless="no.bundle">
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -16,18 +16,22 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
fi
|
||||
|
||||
# on windows, one must specify the path of commnad find
|
||||
# since windows has its own retarded version of find.
|
||||
# since windows has its own version of find.
|
||||
if which find|grep -q -i windows ; then
|
||||
export PATH=.:/bin:/usr/local/bin:$PATH
|
||||
fi
|
||||
# Fast mode - update ondemond
|
||||
# set LG2 to the language you need in envrionment varibales to enable this
|
||||
# set LG2 to the language you need in environment variables to enable this
|
||||
|
||||
# add ../java/ so the refs will work in the po file
|
||||
JPATHS="src"
|
||||
@ -60,19 +64,19 @@ do
|
||||
echo "Updating the $i file from the tags..."
|
||||
# extract strings from java and jsp files, and update messages.po files
|
||||
# translate calls must be one of the forms:
|
||||
# _("foo")
|
||||
# _t("foo")
|
||||
# _x("foo")
|
||||
# intl._("foo")
|
||||
# intl._t("foo")
|
||||
# intl.title("foo")
|
||||
# handler._("foo")
|
||||
# formhandler._("foo")
|
||||
# handler._t("foo")
|
||||
# formhandler._t("foo")
|
||||
# net.i2p.router.web.Messages.getString("foo")
|
||||
# In a jsp, you must use a helper or handler that has the context set.
|
||||
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||
# then ant distclean updater.
|
||||
find $JPATHS -name *.java > $TMPFILE
|
||||
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 --add-comments\
|
||||
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
|
||||
--keyword=_t --keyword=_x --keyword=intl._ --keyword=intl.title \
|
||||
--keyword=handler._ --keyword=formhandler._ \
|
||||
--keyword=net.i2p.router.web.Messages.getString \
|
||||
-o ${i}t
|
||||
|
@ -11,6 +11,7 @@ msgstr ""
|
||||
"POT-Creation-Date: 2011-02-20 11:53+0000\n"
|
||||
"PO-Revision-Date: 2011-02-26 19:46-0000\n"
|
||||
"Last-Translator: hamada <hamada@mail.i2p>\n"
|
||||
"Language: ar\n"
|
||||
"Language-Team: duck <duck@mail.i2p>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
@ -3,20 +3,22 @@
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# <kia___@hushmail.com>, 2011.
|
||||
# Translators:
|
||||
# Aesthese, 2016
|
||||
# KIA <kia___@hushmail.com>, 2011
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2011-07-12 19:41+0000\n"
|
||||
"Last-Translator: KIA <kia___@hushmail.com>\n"
|
||||
"Language-Team: Danish (http://www.transifex.net/projects/p/I2P/team/da/)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2016-01-08 07:54+0000\n"
|
||||
"Last-Translator: Aesthese\n"
|
||||
"Language-Team: Danish (http://www.transifex.com/otf/I2P/language/da/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: da\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
@ -24,7 +26,7 @@ msgstr "Start I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P starter nu!"
|
||||
msgstr "I2P starter!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
@ -46,12 +48,10 @@ msgstr "Genstart I2P"
|
||||
msgid "Stop I2P"
|
||||
msgstr "Stop I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Konfiguration af processbar ikonet"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Skal processbar ikonet være aktivt?"
|
||||
|
||||
|
||||
|
@ -3,19 +3,19 @@
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
# foo <foo@bar>, 2009.
|
||||
#
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 18:07+0000\n"
|
||||
"PO-Revision-Date: 2011-03-22 15:49+0000\n"
|
||||
"Last-Translator: blabla <blabla@trash-mail.com>\n"
|
||||
"Language-Team: German <>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
@ -46,10 +46,10 @@ msgstr "I2P neustarten"
|
||||
msgid "Stop I2P"
|
||||
msgstr "I2P beenden"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Systemleistensymbol konfigurieren"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Systemleistensymbol aktivieren?"
|
||||
|
@ -8,11 +8,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P desktopgui\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
|
||||
"Last-Translator: duck <duck@mail.i2p>\n"
|
||||
"Language-Team: duck <duck@mail.i2p>\n"
|
||||
"Language: \n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@ -46,10 +46,10 @@ msgstr ""
|
||||
msgid "Stop I2P"
|
||||
msgstr ""
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr ""
|
||||
|
@ -2,7 +2,7 @@
|
||||
# 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:
|
||||
# blabla <blabla@trash-mail.com>, 2011
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
@ -11,15 +11,16 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:14+0000\n"
|
||||
"PO-Revision-Date: 2013-06-08 04:50+0000\n"
|
||||
"Last-Translator: Boxoa590\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/fr/)\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"fr/)\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: fr\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
@ -50,10 +51,10 @@ msgstr "Redémarrer I2P"
|
||||
msgid "Stop I2P"
|
||||
msgstr "Arrêter I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Configuration de l'icône de notification"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Activer l'icône de notification ?"
|
||||
|
56
apps/desktopgui/locale/messages_ja.po
Normal file
56
apps/desktopgui/locale/messages_ja.po
Normal file
@ -0,0 +1,56 @@
|
||||
# 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:
|
||||
# plazmism <gomidori@live.jp>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2013-11-26 10:38+0000\n"
|
||||
"Last-Translator: plazmism <gomidori@live.jp>\n"
|
||||
"Language-Team: Japanese (http://www.transifex.com/projects/p/I2P/language/ja/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ja\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
msgstr "I2P を開始"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P 起動中!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
msgstr "起動中"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "I2P ブラウザを起動"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
msgstr "desktopgui を設定"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
||||
msgid "Restart I2P"
|
||||
msgstr "I2P を再起動"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
||||
msgid "Stop I2P"
|
||||
msgstr "I2P を停止"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "トレイアイコン設定"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "トレイアイコンを有効にしますか?"
|
@ -3,20 +3,22 @@
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# <b790979@klzlk.com>, 2011.
|
||||
# Translators:
|
||||
# PolishAnon <b790979@klzlk.com>, 2011
|
||||
# polacco <polacco@i2pmail.org>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2011-05-25 18:36+0000\n"
|
||||
"Last-Translator: PolishAnon <b790979@klzlk.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.net/projects/p/I2P/team/pl/)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2015-02-17 20:54+0000\n"
|
||||
"Last-Translator: polacco <polacco@i2pmail.org>\n"
|
||||
"Language-Team: Polish (http://www.transifex.com/projects/p/I2P/language/pl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pl\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
@ -32,7 +34,7 @@ msgstr "Uruchamianie"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Uruchom Przeglądarke I2P"
|
||||
msgstr "Uruchom przeglądarkę I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
@ -46,12 +48,10 @@ msgstr "Zrestartuj I2P"
|
||||
msgid "Stop I2P"
|
||||
msgstr "Zatrzymaj I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Konfiguracja ikony zasobnika"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Czy ikona zasobnika powinna być aktywna?"
|
||||
|
||||
|
||||
|
58
apps/desktopgui/locale/messages_pt_BR.po
Normal file
58
apps/desktopgui/locale/messages_pt_BR.po
Normal file
@ -0,0 +1,58 @@
|
||||
# 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:
|
||||
# testsubject67 <deborinha97@hotmail.com>, 2014
|
||||
# blueboy, 2013
|
||||
# blueboy, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2015-12-23 00:12+0000\n"
|
||||
"Last-Translator: blueboy\n"
|
||||
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/otf/I2P/language/pt_BR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_BR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
msgstr "Conectar-se à I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "Conectando-se a I2P!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
msgstr "Conectando"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Lançar o navegador I2P "
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
msgstr "Configurar desktopgui"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
||||
msgid "Restart I2P"
|
||||
msgstr "Reinicializar o roteador I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
||||
msgid "Stop I2P"
|
||||
msgstr "Interromper o roteador I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Configuração do ícone de bandeja"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Ativar ícone de bandeja?"
|
57
apps/desktopgui/locale/messages_ro.po
Normal file
57
apps/desktopgui/locale/messages_ro.po
Normal file
@ -0,0 +1,57 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:03+0000\n"
|
||||
"PO-Revision-Date: 2013-11-11 11:31+0000\n"
|
||||
"Last-Translator: polearnik <polearnik@mail.ru>\n"
|
||||
"Language-Team: Romanian (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"ro/)\n"
|
||||
"Language: ro\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
|
||||
"2:1));\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
msgstr "Start I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P se pornește!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
msgstr "Începere"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Lansare I2P Browser"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
msgstr "Configurarea desktopgui"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
||||
msgid "Restart I2P"
|
||||
msgstr "Restart I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
||||
msgid "Stop I2P"
|
||||
msgstr "Stop I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Configurare pictogramei din bara de sistem"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Ar trebui să fie activata pictograma din bara de sistem?"
|
@ -6,14 +6,14 @@
|
||||
# Translators:
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# Roman Azarenko <x12ozmouse@ya.ru>, 2013
|
||||
# Роман Азаренко <transifex@basicxp.ru>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2013-07-07 11:44+0000\n"
|
||||
"Last-Translator: Roman Azarenko <x12ozmouse@ya.ru>\n"
|
||||
"PO-Revision-Date: 2013-12-04 11:46+0000\n"
|
||||
"Last-Translator: Bergitte <alvina_alexandrova@mail.ru>\n"
|
||||
"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/I2P/language/ru_RU/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
57
apps/desktopgui/locale/messages_sk.po
Normal file
57
apps/desktopgui/locale/messages_sk.po
Normal file
@ -0,0 +1,57 @@
|
||||
# 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:
|
||||
# Krantišek <jaksrn@gmail.com>, 2014
|
||||
# Svistwarrior273 <romanbeno273@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2014-04-20 09:56+0000\n"
|
||||
"Last-Translator: Svistwarrior273 <romanbeno273@gmail.com>\n"
|
||||
"Language-Team: Slovak (http://www.transifex.com/projects/p/I2P/language/sk/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: sk\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
msgstr "Spustiť I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P sa spúšťa!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
||||
msgid "Starting"
|
||||
msgstr "Spúšťa sa"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Spustiť I2P prehliadač"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
||||
msgid "Configure desktopgui"
|
||||
msgstr "Nakonfigurovať desktopgui"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
||||
msgid "Restart I2P"
|
||||
msgstr "Reštartovať I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
||||
msgid "Stop I2P"
|
||||
msgstr "Zastaviť I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Konfigurácia ikony v lište"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Mala by byť ikona v lište povolená?"
|
@ -3,20 +3,23 @@
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# <gribua@gmail.com>, 2011.
|
||||
# Translators:
|
||||
# Denis Lysenko <gribua@gmail.com>, 2011
|
||||
# LinuxChata, 2014
|
||||
# madjong <madjong@i2pmail.org>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
|
||||
"PO-Revision-Date: 2011-06-19 14:01+0000\n"
|
||||
"Last-Translator: Pharmasolin <gribua@gmail.com>\n"
|
||||
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.net/projects/p/I2P/team/uk_UA/)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
||||
"PO-Revision-Date: 2015-08-07 16:31+0000\n"
|
||||
"Last-Translator: Denis Lysenko <gribua@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"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: uk_UA\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
||||
msgid "Start I2P"
|
||||
@ -46,12 +49,10 @@ msgstr "Перезапустити I2P"
|
||||
msgid "Stop I2P"
|
||||
msgstr "Зупинити I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
||||
msgid "Tray icon configuration"
|
||||
msgstr "Настройка трей-іконки"
|
||||
msgstr "Налаштування трей-іконки"
|
||||
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
||||
msgid "Should tray icon be enabled?"
|
||||
msgstr "Чм повинна трей-іконка бути включена?"
|
||||
|
||||
|
||||
msgstr "Чи повинна трей-іконка бути включена?"
|
||||
|
@ -20,7 +20,7 @@ public class ExternalTrayManager extends TrayManager {
|
||||
@Override
|
||||
public PopupMenu getMainMenu() {
|
||||
PopupMenu popup = new PopupMenu();
|
||||
MenuItem startItem = new MenuItem(_("Start I2P"));
|
||||
MenuItem startItem = new MenuItem(_t("Start I2P"));
|
||||
startItem.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
@ -35,7 +35,7 @@ public class ExternalTrayManager extends TrayManager {
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
trayIcon.displayMessage(_("Starting"), _("I2P is starting!"), TrayIcon.MessageType.INFO);
|
||||
trayIcon.displayMessage(_t("Starting"), _t("I2P is starting!"), TrayIcon.MessageType.INFO);
|
||||
//Hide the tray icon.
|
||||
//We cannot stop the desktopgui program entirely,
|
||||
//since that risks killing the I2P process as well.
|
||||
|
@ -23,7 +23,7 @@ public class InternalTrayManager extends TrayManager {
|
||||
public PopupMenu getMainMenu() {
|
||||
PopupMenu popup = new PopupMenu();
|
||||
|
||||
MenuItem browserLauncher = new MenuItem(_("Launch I2P Browser"));
|
||||
MenuItem browserLauncher = new MenuItem(_t("Launch I2P Browser"));
|
||||
browserLauncher.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
@ -47,7 +47,7 @@ public class InternalTrayManager extends TrayManager {
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
MenuItem desktopguiConfigurationLauncher = new MenuItem(_("Configure desktopgui"));
|
||||
MenuItem desktopguiConfigurationLauncher = new MenuItem(_t("Configure desktopgui"));
|
||||
desktopguiConfigurationLauncher.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
@ -64,7 +64,7 @@ public class InternalTrayManager extends TrayManager {
|
||||
}
|
||||
|
||||
});
|
||||
MenuItem restartItem = new MenuItem(_("Restart I2P"));
|
||||
MenuItem restartItem = new MenuItem(_t("Restart I2P"));
|
||||
restartItem.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
@ -82,7 +82,7 @@ public class InternalTrayManager extends TrayManager {
|
||||
}
|
||||
|
||||
});
|
||||
MenuItem stopItem = new MenuItem(_("Stop I2P"));
|
||||
MenuItem stopItem = new MenuItem(_t("Stop I2P"));
|
||||
stopItem.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
|
@ -7,9 +7,6 @@ package net.i2p.desktopgui;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.desktopgui.router.RouterManager;
|
||||
import net.i2p.desktopgui.util.*;
|
||||
import net.i2p.util.Log;
|
||||
|
@ -1,28 +1,15 @@
|
||||
package net.i2p.desktopgui;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Image;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.Desktop.Action;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import net.i2p.desktopgui.i18n.DesktopguiTranslator;
|
||||
import net.i2p.desktopgui.router.RouterManager;
|
||||
import net.i2p.desktopgui.util.BrowseException;
|
||||
import net.i2p.desktopgui.util.ConfigurationManager;
|
||||
import net.i2p.desktopgui.util.I2PDesktop;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -91,7 +78,7 @@ public abstract class TrayManager {
|
||||
return image;
|
||||
}
|
||||
|
||||
protected static String _(String s) {
|
||||
return DesktopguiTranslator._(s);
|
||||
protected static String _t(String s) {
|
||||
return DesktopguiTranslator._t(s);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
@ -41,10 +40,10 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
|
||||
cancelButton = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(_("Tray icon configuration"));
|
||||
setTitle(_t("Tray icon configuration"));
|
||||
|
||||
desktopguiEnabled.setSelected(true);
|
||||
desktopguiEnabled.setText(_("Should tray icon be enabled?"));
|
||||
desktopguiEnabled.setText(_t("Should tray icon be enabled?"));
|
||||
desktopguiEnabled.setActionCommand("shouldDesktopguiBeEnabled");
|
||||
|
||||
okButton.setText("OK");
|
||||
@ -99,8 +98,8 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
|
||||
configureDesktopgui();
|
||||
}//GEN-LAST:event_okButtonMouseReleased
|
||||
|
||||
protected static String _(String s) {
|
||||
return DesktopguiTranslator._(s);
|
||||
protected static String _t(String s) {
|
||||
return DesktopguiTranslator._t(s);
|
||||
}
|
||||
|
||||
private void configureDesktopgui() {
|
||||
@ -115,7 +114,7 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
|
||||
System.out.println("Enabling desktopgui");
|
||||
}
|
||||
try {
|
||||
RouterManager.getRouterContext().setProperty(property, value);
|
||||
RouterManager.getRouterContext().router().saveConfig(property, value);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DesktopguiConfigurationFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
@ -16,11 +16,11 @@ public class DesktopguiTranslator {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public static String _(String s) {
|
||||
public static String _t(String s) {
|
||||
return Translate.getString(s, getRouterContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
public static String _(String s, Object o) {
|
||||
public static String _t(String s, Object o) {
|
||||
return Translate.getString(s, o, getRouterContext(), BUNDLE_NAME);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import java.io.IOException;
|
||||
import org.tanukisoftware.wrapper.WrapperManager;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.desktopgui.i18n.DesktopguiTranslator;
|
||||
import net.i2p.desktopgui.util.ConfigurationManager;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
@ -78,7 +78,7 @@ public class ConfigurationManager {
|
||||
* @return The value of a configuration: true if found, defaultValue if not found.
|
||||
*/
|
||||
public boolean getBooleanConfiguration(String arg, boolean defaultValue) {
|
||||
Boolean value = ((Boolean) booleanConfigurations.get("startWithI2P"));
|
||||
Boolean value = booleanConfigurations.get("startWithI2P");
|
||||
System.out.println(value);
|
||||
if(value != null) {
|
||||
return value;
|
||||
|
@ -1,13 +1,8 @@
|
||||
package net.i2p.desktopgui.util;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.Desktop.Action;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import net.i2p.desktopgui.router.RouterManager;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2PDesktop {
|
||||
|
@ -1,11 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="java/src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/ministreaming"/>
|
||||
<classpathentry kind="lib" path="/jetty/jettylib/javax.servlet.jar"/>
|
||||
<classpathentry kind="lib" path="/jetty/jettylib/jetty-util.jar"/>
|
||||
<classpathentry kind="lib" path="/jetty/jettylib/org.mortbay.jetty.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/jetty"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/ministreaming"/>
|
||||
<classpathentry kind="output" path="java/build/obj"/>
|
||||
</classpath>
|
||||
|
@ -1,340 +1 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
See ../../licenses/LICENSE-GPLv2.txt
|
||||
|
@ -1,24 +0,0 @@
|
||||
- I2PSnark:
|
||||
- add multitorrent support by checking the metainfo hash in the
|
||||
PeerAcceptor and feeding it off to the appropriate coordinator
|
||||
- add a web interface
|
||||
|
||||
- BEncode
|
||||
- Byte array length indicator can overflow.
|
||||
- Support really big BigNums (only 256 chars allowed now)
|
||||
- Better BEValue toString(). Uses stupid heuristic now for debugging.
|
||||
- Implemented bencoding.
|
||||
- Remove application level hack to calculate sha1 hash for metainfo
|
||||
(But can it be done as efficiently?)
|
||||
|
||||
- Storage
|
||||
- Check file name filter.
|
||||
|
||||
- TrackerClient
|
||||
- Support undocumented &numwant= request.
|
||||
|
||||
- PeerCoordinator
|
||||
- Disconnect from other seeds as soon as you are a seed yourself.
|
||||
|
||||
- Text UI
|
||||
- Make it completely silent.
|
@ -17,29 +17,28 @@
|
||||
<classpath>
|
||||
<pathelement location="../../../core/java/build/obj" />
|
||||
<pathelement location="../../ministreaming/java/build/obj" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
</classpath>
|
||||
</depend>
|
||||
</target>
|
||||
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<condition property="no.bundle">
|
||||
<isfalse value="${require.gettext}" />
|
||||
</condition>
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<target name="compile" depends="depend">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true" deprecation="on" source="1.5" target="1.5"
|
||||
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||
destdir="./build/obj"
|
||||
includeAntRuntime="false"
|
||||
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jetty/jettylib/jetty-servlet.jar:../../jetty/jettylib/jetty-util.jar:../../ministreaming/java/build/mstreaming.jar" >
|
||||
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" >
|
||||
<compilerarg line="${javac.compilerargs}" />
|
||||
</javac>
|
||||
</target>
|
||||
@ -101,15 +100,15 @@
|
||||
<target name="war" depends="jar, bundle, warUpToDate, listChangedFiles" unless="war.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<copy todir="build/icons/.icons" >
|
||||
<fileset dir="../icons/" />
|
||||
<copy todir="build/resources/.resources" >
|
||||
<fileset dir="../resources/" />
|
||||
</copy>
|
||||
<!-- mime.properties must be in with the classes -->
|
||||
<copy file="../mime.properties" todir="build/obj/org/klomp/snark/web" />
|
||||
<war destfile="../i2psnark.war" webxml="../web.xml" >
|
||||
<!-- include only the web stuff, as of 0.7.12 the router will add i2psnark.jar to the classpath for the war -->
|
||||
<classes dir="./build/obj" includes="**/web/*" />
|
||||
<fileset dir="build/icons/" />
|
||||
<fileset dir="build/resources/" />
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
@ -122,7 +121,7 @@
|
||||
|
||||
<target name="warUpToDate">
|
||||
<uptodate property="war.uptodate" targetfile="../i2psnark.war" >
|
||||
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../icons/* ../web.xml" />
|
||||
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../resources/**/* ../web.xml" />
|
||||
</uptodate>
|
||||
</target>
|
||||
|
||||
@ -130,6 +129,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,18 +15,22 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
fi
|
||||
|
||||
# on windows, one must specify the path of commnad find
|
||||
# since windows has its own retarded version of find.
|
||||
# since windows has its own version of find.
|
||||
if which find|grep -q -i windows ; then
|
||||
export PATH=.:/bin:/usr/local/bin:$PATH
|
||||
fi
|
||||
# Fast mode - update ondemond
|
||||
# set LG2 to the language you need in envrionment varibales to enable this
|
||||
# set LG2 to the language you need in environment variables to enable this
|
||||
|
||||
# add ../java/ so the refs will work in the po file
|
||||
JPATHS="../java/src"
|
||||
@ -59,13 +63,13 @@ do
|
||||
echo "Updating the $i file from the tags..."
|
||||
# extract strings from java and jsp files, and update messages.po files
|
||||
# translate calls must be one of the forms:
|
||||
# _("foo")
|
||||
# _t("foo")
|
||||
# _x("foo")
|
||||
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||
# then ant distclean poupdate.
|
||||
find $JPATHS -name *.java > $TMPFILE
|
||||
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 --add-comments\
|
||||
--keyword=_ --keyword=_x \
|
||||
--keyword=_t --keyword=_x \
|
||||
-o ${i}t
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
package org.klomp.snark;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.client.I2PSessionException;
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
package org.klomp.snark;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Container of a byte array representing set and unset bits.
|
||||
@ -66,7 +68,7 @@ public class BitField
|
||||
|
||||
/**
|
||||
* This returns the actual byte array used. Changes to this array
|
||||
* effect this BitField. Note that some bits at the end of the byte
|
||||
* affect this BitField. Note that some bits at the end of the byte
|
||||
* array are supposed to be always unset if they represent bits
|
||||
* bigger then the size of the bitfield.
|
||||
*/
|
||||
@ -105,6 +107,37 @@ public class BitField
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given bit to false.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if bit is smaller then zero
|
||||
* bigger then size (inclusive).
|
||||
* @since 0.9.22
|
||||
*/
|
||||
public void clear(int bit)
|
||||
{
|
||||
if (bit < 0 || bit >= size)
|
||||
throw new IndexOutOfBoundsException(Integer.toString(bit));
|
||||
int index = bit/8;
|
||||
int mask = 128 >> (bit % 8);
|
||||
synchronized(this) {
|
||||
if ((bitfield[index] & mask) != 0) {
|
||||
count--;
|
||||
bitfield[index] &= ~mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all bits to true.
|
||||
*
|
||||
* @since 0.9.21
|
||||
*/
|
||||
public void setAll() {
|
||||
Arrays.fill(bitfield, (byte) 0xff);
|
||||
count = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bit is set or false if it is not.
|
||||
*
|
||||
|
@ -54,7 +54,15 @@ public interface CompleteListener {
|
||||
*/
|
||||
public void gotPiece(Snark snark);
|
||||
|
||||
// not really listeners but the easiest way to get back to an optional SnarkManager
|
||||
/** not really listeners but the easiest way to get back to an optional SnarkManager */
|
||||
public long getSavedTorrentTime(Snark snark);
|
||||
public BitField getSavedTorrentBitField(Snark snark);
|
||||
/**
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public boolean getSavedPreserveNamesSetting(Snark snark);
|
||||
/**
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public long getSavedUploaded(Snark snark);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ConnectException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
@ -41,51 +42,49 @@ import net.i2p.util.SimpleTimer2;
|
||||
class ConnectionAcceptor implements Runnable
|
||||
{
|
||||
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ConnectionAcceptor.class);
|
||||
private I2PServerSocket serverSocket;
|
||||
private PeerAcceptor peeracceptor;
|
||||
private final PeerAcceptor peeracceptor;
|
||||
private Thread thread;
|
||||
private final I2PSnarkUtil _util;
|
||||
private final ObjectCounter<Hash> _badCounter = new ObjectCounter();
|
||||
private final ObjectCounter<Hash> _badCounter = new ObjectCounter<Hash>();
|
||||
private final SimpleTimer2.TimedEvent _cleaner;
|
||||
|
||||
private volatile boolean stop;
|
||||
private boolean socketChanged;
|
||||
|
||||
// protocol errors before blacklisting.
|
||||
private static final int MAX_BAD = 1;
|
||||
private static final long BAD_CLEAN_INTERVAL = 30*60*1000;
|
||||
|
||||
/**
|
||||
* Multitorrent
|
||||
* Multitorrent. Caller MUST call startAccepting()
|
||||
*/
|
||||
public ConnectionAcceptor(I2PSnarkUtil util) {
|
||||
public ConnectionAcceptor(I2PSnarkUtil util, PeerCoordinatorSet set) {
|
||||
_util = util;
|
||||
_cleaner = new Cleaner();
|
||||
peeracceptor = new PeerAcceptor(set);
|
||||
}
|
||||
|
||||
public synchronized void startAccepting(PeerCoordinatorSet set, I2PServerSocket socket) {
|
||||
if (serverSocket != socket) {
|
||||
if ( (peeracceptor == null) || (peeracceptor.coordinators != set) )
|
||||
peeracceptor = new PeerAcceptor(set);
|
||||
serverSocket = socket;
|
||||
/**
|
||||
* May be called even when already running. May be called to start up again after halt().
|
||||
*/
|
||||
public synchronized void startAccepting() {
|
||||
stop = false;
|
||||
socketChanged = true;
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("ConnectionAcceptor startAccepting new thread? " + (thread == null));
|
||||
if (thread == null) {
|
||||
thread = new I2PAppThread(this, "I2PSnark acceptor");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
_cleaner.schedule(BAD_CLEAN_INTERVAL);
|
||||
_cleaner.reschedule(BAD_CLEAN_INTERVAL, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused (single torrent)
|
||||
* Unused (single torrent).
|
||||
* Do NOT call startAccepting().
|
||||
*/
|
||||
public ConnectionAcceptor(I2PSnarkUtil util, I2PServerSocket serverSocket,
|
||||
public ConnectionAcceptor(I2PSnarkUtil util,
|
||||
PeerAcceptor peeracceptor)
|
||||
{
|
||||
this.serverSocket = serverSocket;
|
||||
this.peeracceptor = peeracceptor;
|
||||
_util = util;
|
||||
|
||||
@ -95,55 +94,79 @@ class ConnectionAcceptor implements Runnable
|
||||
_cleaner = new Cleaner();
|
||||
}
|
||||
|
||||
public void halt()
|
||||
/**
|
||||
* May be restarted later with startAccepting().
|
||||
*/
|
||||
public synchronized void halt()
|
||||
{
|
||||
if (stop) return;
|
||||
stop = true;
|
||||
locked_halt();
|
||||
Thread t = thread;
|
||||
if (t != null) {
|
||||
t.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
I2PServerSocket ss = serverSocket;
|
||||
if (ss != null)
|
||||
|
||||
/**
|
||||
* Caller must synch
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private void locked_halt()
|
||||
{
|
||||
I2PServerSocket ss = _util.getServerSocket();
|
||||
if (ss != null) {
|
||||
try
|
||||
{
|
||||
ss.close();
|
||||
}
|
||||
catch(I2PException ioe) { }
|
||||
|
||||
Thread t = thread;
|
||||
if (t != null)
|
||||
t.interrupt();
|
||||
}
|
||||
_badCounter.clear();
|
||||
_cleaner.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Effectively unused, would only be called if we changed
|
||||
* I2CP host/port, which is hidden in the gui if in router context
|
||||
* FIXME this only works if already running
|
||||
*/
|
||||
public void restart() {
|
||||
serverSocket = _util.getServerSocket();
|
||||
socketChanged = true;
|
||||
public synchronized void restart() {
|
||||
Thread t = thread;
|
||||
if (t != null)
|
||||
t.interrupt();
|
||||
_cleaner.schedule(BAD_CLEAN_INTERVAL);
|
||||
}
|
||||
|
||||
public int getPort()
|
||||
{
|
||||
return 6881; // serverSocket.getLocalPort();
|
||||
return TrackerClient.PORT; // serverSocket.getLocalPort();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
run2();
|
||||
} finally {
|
||||
synchronized(this) {
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void run2()
|
||||
{
|
||||
while(!stop)
|
||||
{
|
||||
if (socketChanged) {
|
||||
// ok, already updated
|
||||
socketChanged = false;
|
||||
}
|
||||
I2PServerSocket serverSocket = _util.getServerSocket();
|
||||
while ( (serverSocket == null) && (!stop)) {
|
||||
if (!(_util.isConnecting() || _util.connected())) {
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
serverSocket = _util.getServerSocket();
|
||||
if (serverSocket == null)
|
||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
}
|
||||
if(stop)
|
||||
break;
|
||||
@ -151,25 +174,25 @@ class ConnectionAcceptor implements Runnable
|
||||
{
|
||||
I2PSocket socket = serverSocket.accept();
|
||||
if (socket == null) {
|
||||
if (socketChanged) {
|
||||
continue;
|
||||
} else {
|
||||
I2PServerSocket ss = _util.getServerSocket();
|
||||
if (ss != serverSocket) {
|
||||
serverSocket = ss;
|
||||
socketChanged = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (socket.getPeerDestination().equals(_util.getMyDestination())) {
|
||||
_log.error("Incoming connection from myself");
|
||||
try { socket.close(); } catch (IOException ioe) {}
|
||||
continue;
|
||||
}
|
||||
int bad = _badCounter.count(socket.getPeerDestination().calculateHash());
|
||||
Hash h = socket.getPeerDestination().calculateHash();
|
||||
if (socket.getLocalPort() == 80) {
|
||||
_badCounter.increment(h);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.error("Dropping incoming HTTP from " + h);
|
||||
try { socket.close(); } catch (IOException ioe) {}
|
||||
continue;
|
||||
}
|
||||
int bad = _badCounter.count(h);
|
||||
if (bad >= MAX_BAD) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting connection from " + socket.getPeerDestination().calculateHash() +
|
||||
_log.warn("Rejecting connection from " + h +
|
||||
" after " + bad + " failures, max is " + MAX_BAD);
|
||||
try { socket.close(); } catch (IOException ioe) {}
|
||||
continue;
|
||||
@ -180,26 +203,48 @@ class ConnectionAcceptor implements Runnable
|
||||
}
|
||||
catch (I2PException ioe)
|
||||
{
|
||||
if (!socketChanged) {
|
||||
_log.error("Error while accepting", ioe);
|
||||
stop = true;
|
||||
int level = stop ? Log.WARN : Log.ERROR;
|
||||
if (_log.shouldLog(level))
|
||||
_log.log(level, "Error while accepting", ioe);
|
||||
synchronized(this) {
|
||||
if (!stop) {
|
||||
locked_halt();
|
||||
thread = null;
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ConnectException ioe)
|
||||
{
|
||||
// This is presumed to be due to socket closing by I2PSnarkUtil.disconnect(),
|
||||
// which does not currently call our halt(), although it should
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Error while accepting", ioe);
|
||||
synchronized(this) {
|
||||
if (!stop) {
|
||||
locked_halt();
|
||||
thread = null;
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
_log.error("Error while accepting", ioe);
|
||||
stop = true;
|
||||
int level = stop ? Log.WARN : Log.ERROR;
|
||||
if (_log.shouldLog(level))
|
||||
_log.log(level, "Error while accepting", ioe);
|
||||
synchronized(this) {
|
||||
if (!stop) {
|
||||
locked_halt();
|
||||
thread = null;
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// catch oom?
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (serverSocket != null)
|
||||
serverSocket.close();
|
||||
}
|
||||
catch (I2PException ignored) { }
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("ConnectionAcceptor closed");
|
||||
}
|
||||
|
||||
private class Handler implements Runnable {
|
||||
|
@ -31,7 +31,7 @@ abstract class ExtensionHandler {
|
||||
public static final int ID_DHT = 3;
|
||||
/** not using the option bit since the compact format is different */
|
||||
public static final String TYPE_DHT = "i2p_dht";
|
||||
/** Pieces * SHA1 Hash length, + 25% extra for file names, benconding overhead, etc */
|
||||
/** Pieces * SHA1 Hash length, + 25% extra for file names, bencoding overhead, etc */
|
||||
private static final int MAX_METADATA_SIZE = Storage.MAX_PIECES * 20 * 5 / 4;
|
||||
private static final int PARALLEL_REQUESTS = 3;
|
||||
|
||||
@ -42,9 +42,9 @@ abstract class ExtensionHandler {
|
||||
* @param dht advertise DHT capability
|
||||
* @return bencoded outgoing handshake message
|
||||
*/
|
||||
public static byte[] getHandshake(int metasize, boolean pexAndMetadata, boolean dht) {
|
||||
Map<String, Object> handshake = new HashMap();
|
||||
Map<String, Integer> m = new HashMap();
|
||||
public static byte[] getHandshake(int metasize, boolean pexAndMetadata, boolean dht, boolean uploadOnly) {
|
||||
Map<String, Object> handshake = new HashMap<String, Object>();
|
||||
Map<String, Integer> m = new HashMap<String, Integer>();
|
||||
if (pexAndMetadata) {
|
||||
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
|
||||
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
|
||||
@ -56,9 +56,12 @@ abstract class ExtensionHandler {
|
||||
}
|
||||
// include the map even if empty so the far-end doesn't NPE
|
||||
handshake.put("m", m);
|
||||
handshake.put("p", Integer.valueOf(6881));
|
||||
handshake.put("p", Integer.valueOf(TrackerClient.PORT));
|
||||
handshake.put("v", "I2PSnark");
|
||||
handshake.put("reqq", Integer.valueOf(5));
|
||||
// BEP 21
|
||||
if (uploadOnly)
|
||||
handshake.put("upload_only", Integer.valueOf(1));
|
||||
return BEncoder.bencode(handshake);
|
||||
}
|
||||
|
||||
@ -90,17 +93,20 @@ abstract class ExtensionHandler {
|
||||
peer.setHandshakeMap(map);
|
||||
Map<String, BEValue> msgmap = map.get("m").getMap();
|
||||
|
||||
if (msgmap.get(TYPE_PEX) != null) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer supports PEX extension: " + peer);
|
||||
// peer state calls peer listener calls sendPEX()
|
||||
}
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer " + peer + " supports extensions: " + msgmap.keySet());
|
||||
|
||||
if (msgmap.get(TYPE_DHT) != null) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Peer supports DHT extension: " + peer);
|
||||
// peer state calls peer listener calls sendDHT()
|
||||
}
|
||||
//if (msgmap.get(TYPE_PEX) != null) {
|
||||
// if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Peer supports PEX extension: " + peer);
|
||||
// // peer state calls peer listener calls sendPEX()
|
||||
//}
|
||||
|
||||
//if (msgmap.get(TYPE_DHT) != null) {
|
||||
// if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Peer supports DHT extension: " + peer);
|
||||
// // peer state calls peer listener calls sendDHT()
|
||||
//}
|
||||
|
||||
MagnetState state = peer.getMagnetState();
|
||||
|
||||
@ -110,7 +116,8 @@ abstract class ExtensionHandler {
|
||||
// drop if we need metainfo and we haven't found anybody yet
|
||||
synchronized(state) {
|
||||
if (!state.isInitialized()) {
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
peer.disconnect();
|
||||
}
|
||||
}
|
||||
@ -124,7 +131,8 @@ abstract class ExtensionHandler {
|
||||
// drop if we need metainfo and we haven't found anybody yet
|
||||
synchronized(state) {
|
||||
if (!state.isInitialized()) {
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Dropping peer, we need metadata! " + peer);
|
||||
peer.disconnect();
|
||||
}
|
||||
}
|
||||
@ -202,30 +210,31 @@ abstract class ExtensionHandler {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got request for " + piece + " from: " + peer);
|
||||
byte[] pc;
|
||||
int totalSize;
|
||||
synchronized(state) {
|
||||
pc = state.getChunk(piece);
|
||||
totalSize = state.getSize();
|
||||
}
|
||||
sendPiece(peer, piece, pc);
|
||||
sendPiece(peer, piece, pc, totalSize);
|
||||
// Do this here because PeerConnectionOut only reports for PIECE messages
|
||||
peer.uploaded(pc.length);
|
||||
listener.uploaded(peer, pc.length);
|
||||
} else if (type == TYPE_DATA) {
|
||||
int size = map.get("total_size").getInt();
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Got data for " + piece + " length " + size + " from: " + peer);
|
||||
// On close reading of BEP 9, this is the total metadata size.
|
||||
// Prior to 0.9.21, we sent the piece size, so we can't count on it.
|
||||
// just ignore it. The actual length will be verified in saveChunk()
|
||||
//int size = map.get("total_size").getInt();
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Got data for " + piece + " length " + size + " from: " + peer);
|
||||
boolean done;
|
||||
int chk = -1;
|
||||
synchronized(state) {
|
||||
if (state.isComplete())
|
||||
return;
|
||||
int len = is.available();
|
||||
if (len != size) {
|
||||
// probably fatal
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("total_size " + size + " but avail data " + len);
|
||||
}
|
||||
peer.downloaded(len);
|
||||
listener.downloaded(peer, len);
|
||||
// this checks the size
|
||||
done = state.saveChunk(piece, bs, bs.length - len, len);
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Got chunk " + piece + " from " + peer);
|
||||
@ -274,7 +283,7 @@ abstract class ExtensionHandler {
|
||||
|
||||
/** REQUEST and REJECT are the same except for message type */
|
||||
private static void sendMessage(Peer peer, int type, int piece) {
|
||||
Map<String, Object> map = new HashMap();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("msg_type", Integer.valueOf(type));
|
||||
map.put("piece", Integer.valueOf(piece));
|
||||
byte[] payload = BEncoder.bencode(map);
|
||||
@ -288,11 +297,15 @@ abstract class ExtensionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendPiece(Peer peer, int piece, byte[] data) {
|
||||
Map<String, Object> map = new HashMap();
|
||||
private static void sendPiece(Peer peer, int piece, byte[] data, int totalSize) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("msg_type", Integer.valueOf(TYPE_DATA));
|
||||
map.put("piece", Integer.valueOf(piece));
|
||||
map.put("total_size", Integer.valueOf(data.length));
|
||||
// BEP 9
|
||||
// "This key has the same semantics as the 'metadata_size' in the extension header"
|
||||
// which apparently means the same value. Fixed in 0.9.21.
|
||||
//map.put("total_size", Integer.valueOf(data.length));
|
||||
map.put("total_size", Integer.valueOf(totalSize));
|
||||
byte[] dict = BEncoder.bencode(map);
|
||||
byte[] payload = new byte[dict.length + data.length];
|
||||
System.arraycopy(dict, 0, payload, 0, dict.length);
|
||||
@ -332,7 +345,7 @@ abstract class ExtensionHandler {
|
||||
if (ids.length < HASH_LENGTH)
|
||||
return;
|
||||
int len = Math.min(ids.length, (I2PSnarkUtil.MAX_CONNECTIONS - 1) * HASH_LENGTH);
|
||||
List<PeerID> peers = new ArrayList(len / HASH_LENGTH);
|
||||
List<PeerID> peers = new ArrayList<PeerID>(len / HASH_LENGTH);
|
||||
for (int off = 0; off < len; off += HASH_LENGTH) {
|
||||
byte[] hash = new byte[HASH_LENGTH];
|
||||
System.arraycopy(ids, off, hash, 0, HASH_LENGTH);
|
||||
@ -380,7 +393,7 @@ abstract class ExtensionHandler {
|
||||
public static void sendPEX(Peer peer, List<Peer> pList) {
|
||||
if (pList.isEmpty())
|
||||
return;
|
||||
Map<String, Object> map = new HashMap();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
byte[] peers = new byte[HASH_LENGTH * pList.size()];
|
||||
int off = 0;
|
||||
for (Peer p : pList) {
|
||||
@ -404,7 +417,7 @@ abstract class ExtensionHandler {
|
||||
* @since DHT
|
||||
*/
|
||||
public static void sendDHT(Peer peer, int qport, int rport) {
|
||||
Map<String, Object> map = new HashMap();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("port", Integer.valueOf(qport));
|
||||
map.put("rport", Integer.valueOf(rport));
|
||||
byte[] payload = BEncoder.bencode(map);
|
||||
|
@ -3,18 +3,18 @@ package org.klomp.snark;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
@ -33,7 +33,6 @@ import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFile;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
@ -76,11 +75,10 @@ public class I2PSnarkUtil {
|
||||
private static final int EEPGET_CONNECT_TIMEOUT_SHORT = 5*1000;
|
||||
public static final int DEFAULT_STARTUP_DELAY = 3;
|
||||
public static final boolean DEFAULT_USE_OPENTRACKERS = true;
|
||||
public static final String DEFAULT_OPENTRACKERS = "http://tracker.welterde.i2p/a";
|
||||
public static final int DEFAULT_MAX_UP_BW = 8; //KBps
|
||||
public static final int MAX_CONNECTIONS = 16; // per torrent
|
||||
public static final int MAX_CONNECTIONS = 24; // per torrent
|
||||
public static final String PROP_MAX_BW = "i2cp.outboundBytesPerSecond";
|
||||
public static final boolean DEFAULT_USE_DHT = true;
|
||||
public static final String EEPGET_USER_AGENT = "I2PSnark";
|
||||
|
||||
public I2PSnarkUtil(I2PAppContext ctx) {
|
||||
this(ctx, "i2psnark");
|
||||
@ -94,23 +92,22 @@ public class I2PSnarkUtil {
|
||||
_context = ctx;
|
||||
_log = _context.logManager().getLog(Snark.class);
|
||||
_baseName = baseName;
|
||||
_opts = new HashMap();
|
||||
_opts = new HashMap<String, String>();
|
||||
//setProxy("127.0.0.1", 4444);
|
||||
setI2CPConfig("127.0.0.1", 7654, null);
|
||||
_banlist = new ConcurrentHashSet();
|
||||
_banlist = new ConcurrentHashSet<Hash>();
|
||||
_maxUploaders = Snark.MAX_TOTAL_UPLOADERS;
|
||||
_maxUpBW = DEFAULT_MAX_UP_BW;
|
||||
_maxUpBW = SnarkManager.DEFAULT_MAX_UP_BW;
|
||||
_maxConnections = MAX_CONNECTIONS;
|
||||
_startupDelay = DEFAULT_STARTUP_DELAY;
|
||||
_shouldUseOT = DEFAULT_USE_OPENTRACKERS;
|
||||
// FIXME split if default has more than one
|
||||
_openTrackers = Collections.singletonList(DEFAULT_OPENTRACKERS);
|
||||
_openTrackers = Collections.emptyList();
|
||||
_shouldUseDHT = DEFAULT_USE_DHT;
|
||||
// This is used for both announce replies and .torrent file downloads,
|
||||
// so it must be available even if not connected to I2CP.
|
||||
// so much for multiple instances
|
||||
_tmpDir = new SecureDirectory(ctx.getTempDir(), baseName);
|
||||
FileUtil.rmdir(_tmpDir, false);
|
||||
_tmpDir = new SecureDirectory(ctx.getTempDir(), baseName + '-' + ctx.random().nextInt());
|
||||
//FileUtil.rmdir(_tmpDir, false);
|
||||
_tmpDir.mkdirs();
|
||||
}
|
||||
|
||||
@ -139,6 +136,7 @@ public class I2PSnarkUtil {
|
||||
|
||||
public boolean configured() { return _configured; }
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) {
|
||||
if (i2cpHost != null)
|
||||
_i2cpHost = i2cpHost;
|
||||
@ -220,10 +218,8 @@ public class I2PSnarkUtil {
|
||||
_log.debug("Connecting to I2P", new Exception("I did it"));
|
||||
Properties opts = _context.getProperties();
|
||||
if (_opts != null) {
|
||||
for (Iterator iter = _opts.keySet().iterator(); iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
opts.setProperty(key, _opts.get(key).toString());
|
||||
}
|
||||
for (Map.Entry<String, String> entry : _opts.entrySet() )
|
||||
opts.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (opts.getProperty("inbound.nickname") == null)
|
||||
opts.setProperty("inbound.nickname", _baseName.replace("i2psnark", "I2PSnark"));
|
||||
@ -259,6 +255,10 @@ public class I2PSnarkUtil {
|
||||
opts.setProperty("i2p.streaming.enforceProtocol", "true");
|
||||
if (opts.getProperty("i2p.streaming.disableRejectLogging") == null)
|
||||
opts.setProperty("i2p.streaming.disableRejectLogging", "true");
|
||||
if (opts.getProperty("i2p.streaming.answerPings") == null)
|
||||
opts.setProperty("i2p.streaming.answerPings", "false");
|
||||
if (opts.getProperty(I2PClient.PROP_SIGTYPE) == null)
|
||||
opts.setProperty(I2PClient.PROP_SIGTYPE, "EdDSA_SHA512_Ed25519");
|
||||
_manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
|
||||
_connecting = false;
|
||||
}
|
||||
@ -324,14 +324,18 @@ public class I2PSnarkUtil {
|
||||
if (_banlist.contains(dest))
|
||||
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are banlisted");
|
||||
try {
|
||||
// TODO opts.setPort(xxx); connect(addr, opts)
|
||||
// DHT moved above 6881 in 0.9.9
|
||||
I2PSocket rv = _manager.connect(addr);
|
||||
if (rv != null)
|
||||
_banlist.remove(dest);
|
||||
return rv;
|
||||
} catch (I2PException ie) {
|
||||
_banlist.add(dest);
|
||||
_context.simpleScheduler().addEvent(new Unbanlist(dest), 10*60*1000);
|
||||
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
|
||||
_context.simpleTimer2().addEvent(new Unbanlist(dest), 10*60*1000);
|
||||
IOException ioe = new IOException("Unable to reach the peer " + peer);
|
||||
ioe.initCause(ie);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,6 +398,7 @@ public class I2PSnarkUtil {
|
||||
}
|
||||
}
|
||||
EepGet get = new I2PSocketEepGet(_context, _manager, retries, out.getAbsolutePath(), fetchURL);
|
||||
get.addHeader("User-Agent", EEPGET_USER_AGENT);
|
||||
if (get.fetch(timeout)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetch successful [" + url + "]: size=" + out.length());
|
||||
@ -435,6 +440,7 @@ public class I2PSnarkUtil {
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(initialSize);
|
||||
EepGet get = new I2PSocketEepGet(_context, _manager, retries, -1, maxSize, null, out, fetchURL);
|
||||
get.addHeader("User-Agent", EEPGET_USER_AGENT);
|
||||
if (get.fetch(timeout)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetch successful [" + url + "]: size=" + out.size());
|
||||
@ -454,7 +460,7 @@ public class I2PSnarkUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
String getOurIPString() {
|
||||
public String getOurIPString() {
|
||||
Destination dest = getMyDestination();
|
||||
if (dest != null)
|
||||
return dest.toBase64();
|
||||
@ -513,7 +519,7 @@ public class I2PSnarkUtil {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Using existing session for lookup of " + ip);
|
||||
try {
|
||||
return sess.lookupDest(h);
|
||||
return sess.lookupDest(h, 15*1000);
|
||||
} catch (I2PSessionException ise) {
|
||||
}
|
||||
}
|
||||
@ -563,22 +569,37 @@ public class I2PSnarkUtil {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** @param ot non-null */
|
||||
/** @param ot non-null list of announce URLs */
|
||||
public void setOpenTrackers(List<String> ot) {
|
||||
_openTrackers = ot;
|
||||
}
|
||||
|
||||
/** List of open trackers to use as backups
|
||||
/** List of open tracker announce URLs to use as backups
|
||||
* @return non-null, possibly unmodifiable, empty if disabled
|
||||
*/
|
||||
public List<String> getOpenTrackers() {
|
||||
if (!shouldUseOpenTrackers())
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
return _openTrackers;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of open trackers to use as backups even if disabled
|
||||
* Is this announce URL probably for an open tracker?
|
||||
*
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public boolean isKnownOpenTracker(String url) {
|
||||
try {
|
||||
URI u = new URI(url);
|
||||
String host = u.getHost();
|
||||
return host != null && SnarkManager.KNOWN_OPENTRACKERS.contains(host);
|
||||
} catch (URISyntaxException use) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of open tracker announce URLs to use as backups even if disabled
|
||||
* @return non-null
|
||||
* @since 0.9.4
|
||||
*/
|
||||
@ -640,7 +661,7 @@ public class I2PSnarkUtil {
|
||||
* The {0} will be replaced by the parameter.
|
||||
* Single quotes must be doubled, i.e. ' -> '' in the string.
|
||||
* @param o parameter, not translated.
|
||||
* To tranlslate parameter also, use _("foo {0} bar", _("baz"))
|
||||
* To translate parameter also, use _t("foo {0} bar", _t("baz"))
|
||||
* Do not double the single quotes in the parameter.
|
||||
* Use autoboxing to call with ints, longs, floats, etc.
|
||||
*/
|
||||
|
@ -22,46 +22,79 @@ import net.i2p.util.SimpleTimer2;
|
||||
*/
|
||||
class IdleChecker extends SimpleTimer2.TimedEvent {
|
||||
|
||||
private final SnarkManager _mgr;
|
||||
private final I2PSnarkUtil _util;
|
||||
private final PeerCoordinatorSet _pcs;
|
||||
private final Log _log;
|
||||
private int _consec;
|
||||
private int _consecNotRunning;
|
||||
private boolean _isIdle;
|
||||
private String _lastIn = "3";
|
||||
private String _lastOut = "3";
|
||||
private final Object _lock = new Object();
|
||||
|
||||
private static final long CHECK_TIME = 63*1000;
|
||||
private static final int MAX_CONSEC_IDLE = 4;
|
||||
private static final int MAX_CONSEC_NOT_RUNNING = 20;
|
||||
|
||||
/**
|
||||
* Caller must schedule
|
||||
*/
|
||||
public IdleChecker(I2PSnarkUtil util, PeerCoordinatorSet pcs) {
|
||||
super(util.getContext().simpleTimer2());
|
||||
_log = util.getContext().logManager().getLog(IdleChecker.class);
|
||||
_util = util;
|
||||
public IdleChecker(SnarkManager mgr, PeerCoordinatorSet pcs) {
|
||||
super(mgr.util().getContext().simpleTimer2());
|
||||
_util = mgr.util();
|
||||
_log = _util.getContext().logManager().getLog(IdleChecker.class);
|
||||
_mgr = mgr;
|
||||
_pcs = pcs;
|
||||
}
|
||||
|
||||
public void timeReached() {
|
||||
synchronized (_lock) {
|
||||
locked_timeReached();
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_timeReached() {
|
||||
if (_util.connected()) {
|
||||
boolean hasPeers = false;
|
||||
boolean torrentRunning = false;
|
||||
int peerCount = 0;
|
||||
for (PeerCoordinator pc : _pcs) {
|
||||
if (pc.getPeers() > 0) {
|
||||
hasPeers = true;
|
||||
break;
|
||||
if (!pc.halted()) {
|
||||
torrentRunning = true;
|
||||
peerCount += pc.getPeers();
|
||||
}
|
||||
}
|
||||
if (hasPeers) {
|
||||
if (_isIdle)
|
||||
restoreTunnels();
|
||||
|
||||
if (torrentRunning) {
|
||||
_consecNotRunning = 0;
|
||||
} else {
|
||||
if (_consecNotRunning++ >= MAX_CONSEC_NOT_RUNNING) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Closing tunnels on idle");
|
||||
_util.disconnect();
|
||||
_mgr.addMessage(_util.getString("No more torrents running.") + ' ' +
|
||||
_util.getString("I2P tunnel closed."));
|
||||
schedule(3 * CHECK_TIME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (peerCount > 0) {
|
||||
restoreTunnels(peerCount);
|
||||
} else {
|
||||
if (!_isIdle) {
|
||||
if (_consec++ >= MAX_CONSEC_IDLE)
|
||||
reduceTunnels();
|
||||
else
|
||||
restoreTunnels(1); // pretend we have one peer for now
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_isIdle = false;
|
||||
_consec = 0;
|
||||
_consecNotRunning = 0;
|
||||
_lastIn = "3";
|
||||
_lastOut = "3";
|
||||
}
|
||||
schedule(CHECK_TIME);
|
||||
}
|
||||
@ -77,26 +110,50 @@ class IdleChecker extends SimpleTimer2.TimedEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore tunnel count
|
||||
* Restore or adjust tunnel count based on current peer count
|
||||
* @param peerCount greater than zero
|
||||
*/
|
||||
private void restoreTunnels() {
|
||||
_isIdle = false;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
private void restoreTunnels(int peerCount) {
|
||||
if (_isIdle && _log.shouldLog(Log.INFO))
|
||||
_log.info("Restoring tunnels on activity");
|
||||
_isIdle = false;
|
||||
Map<String, String> opts = _util.getI2CPOptions();
|
||||
String i = opts.get("inbound.quantity");
|
||||
if (i == null)
|
||||
i = "3";
|
||||
i = Integer.toString(SnarkManager.DEFAULT_TUNNEL_QUANTITY);
|
||||
String o = opts.get("outbound.quantity");
|
||||
if (o == null)
|
||||
o = "3";
|
||||
o = Integer.toString(SnarkManager.DEFAULT_TUNNEL_QUANTITY);
|
||||
String ib = opts.get("inbound.backupQuantity");
|
||||
if (ib == null)
|
||||
ib = "0";
|
||||
String ob= opts.get("outbound.backupQuantity");
|
||||
if (ob == null)
|
||||
ob = "0";
|
||||
setTunnels(i, o, ib, ob);
|
||||
// we don't need more tunnels than we have peers, reduce if so
|
||||
// reduce to max(peerCount / 2, 2)
|
||||
int in, out;
|
||||
try {
|
||||
in = Integer.parseInt(i);
|
||||
} catch (NumberFormatException nfe) {
|
||||
in = 3;
|
||||
}
|
||||
try {
|
||||
out = Integer.parseInt(o);
|
||||
} catch (NumberFormatException nfe) {
|
||||
out = 3;
|
||||
}
|
||||
int target = Math.max(peerCount / 2, 2);
|
||||
if (target < in && in > 2) {
|
||||
in = target;
|
||||
i = Integer.toString(in);
|
||||
}
|
||||
if (target < out && out > 2) {
|
||||
out = target;
|
||||
o = Integer.toString(out);
|
||||
}
|
||||
if (!(_lastIn.equals(i) && _lastOut.equals(o)))
|
||||
setTunnels(i, o, ib, ob);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,12 +165,16 @@ class IdleChecker extends SimpleTimer2.TimedEvent {
|
||||
if (mgr != null) {
|
||||
I2PSession sess = mgr.getSession();
|
||||
if (sess != null) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("New tunnel settings " + i + " / " + o + " / " + ib + " / " + ob);
|
||||
Properties newProps = new Properties();
|
||||
newProps.setProperty("inbound.quantity", i);
|
||||
newProps.setProperty("outbound.quantity", o);
|
||||
newProps.setProperty("inbound.backupQuantity", ib);
|
||||
newProps.setProperty("outbound.backupQuantity", ob);
|
||||
sess.updateOptions(newProps);
|
||||
_lastIn = i;
|
||||
_lastOut = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
@ -188,9 +187,9 @@ class MagnetState {
|
||||
* @return true if this was the last piece
|
||||
* @throws NPE, IllegalArgumentException, IOException, ...
|
||||
*/
|
||||
public MetaInfo buildMetaInfo() throws Exception {
|
||||
private MetaInfo buildMetaInfo() throws Exception {
|
||||
// top map has nothing in it but the info map (no announce)
|
||||
Map<String, BEValue> map = new HashMap();
|
||||
Map<String, BEValue> map = new HashMap<String, BEValue>();
|
||||
InputStream is = new ByteArrayInputStream(metainfoBytes);
|
||||
BDecoder dec = new BDecoder(is);
|
||||
BEValue bev = dec.bdecodeMap();
|
||||
|
@ -42,7 +42,7 @@ public class MagnetURI {
|
||||
name = util.getString("Magnet") + ' ' + ihash;
|
||||
String dn = getParam("dn", url);
|
||||
if (dn != null)
|
||||
name += " (" + Storage.filterName(dn) + ')';
|
||||
name += " (" + dn + ')';
|
||||
} else if (url.startsWith(MAGGOT)) {
|
||||
// maggot://0691e40aae02e552cfcb57af1dca56214680c0c5:0b557bbdf8718e95d352fbe994dec3a383e2ede7
|
||||
ihash = url.substring(MAGGOT.length()).trim();
|
||||
@ -82,7 +82,7 @@ public class MagnetURI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pretty name or null
|
||||
* @return pretty name or null, NOT HTML escaped
|
||||
*/
|
||||
public String getName() {
|
||||
return _name;
|
||||
@ -133,7 +133,7 @@ public class MagnetURI {
|
||||
}
|
||||
if (idx < 0 || idx > uri.length())
|
||||
return null;
|
||||
List<String> rv = new ArrayList();
|
||||
List<String> rv = new ArrayList<String>();
|
||||
while (true) {
|
||||
String p = uri.substring(idx);
|
||||
uri = p;
|
||||
@ -175,18 +175,25 @@ public class MagnetURI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode %xx encoding, convert to UTF-8 if necessary
|
||||
* Copied from i2ptunnel LocalHTTPServer
|
||||
* Decode %xx encoding, convert to UTF-8 if necessary.
|
||||
* Copied from i2ptunnel LocalHTTPServer.
|
||||
* Also converts '+' to ' ' so the dn parameter comes out right
|
||||
* These are coming in via a application/x-www-form-urlencoded form so
|
||||
* the pluses are in there...
|
||||
* hopefully any real + is encoded as %2B.
|
||||
*
|
||||
* @since 0.9.1
|
||||
*/
|
||||
private static String decode(String s) {
|
||||
if (!s.contains("%"))
|
||||
if (!(s.contains("%") || s.contains("+")))
|
||||
return s;
|
||||
StringBuilder buf = new StringBuilder(s.length());
|
||||
boolean utf8 = false;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c != '%') {
|
||||
if (c == '+') {
|
||||
buf.append(' ');
|
||||
} else if (c != '%') {
|
||||
buf.append(c);
|
||||
} else {
|
||||
try {
|
||||
|
@ -55,11 +55,13 @@ class Message
|
||||
byte type;
|
||||
|
||||
// Used for HAVE, REQUEST, PIECE and CANCEL messages.
|
||||
// Also SUGGEST, REJECT, ALLOWED_FAST
|
||||
// low byte used for EXTENSION message
|
||||
// low two bytes used for PORT message
|
||||
int piece;
|
||||
|
||||
// Used for REQUEST, PIECE and CANCEL messages.
|
||||
// Also REJECT
|
||||
int begin;
|
||||
int length;
|
||||
|
||||
@ -104,15 +106,18 @@ class Message
|
||||
int datalen = 1;
|
||||
|
||||
// piece is 4 bytes.
|
||||
if (type == HAVE || type == REQUEST || type == PIECE || type == CANCEL)
|
||||
if (type == HAVE || type == REQUEST || type == PIECE || type == CANCEL ||
|
||||
type == SUGGEST || type == REJECT || type == ALLOWED_FAST)
|
||||
datalen += 4;
|
||||
|
||||
// begin/offset is 4 bytes
|
||||
if (type == REQUEST || type == PIECE || type == CANCEL)
|
||||
if (type == REQUEST || type == PIECE || type == CANCEL ||
|
||||
type == REJECT)
|
||||
datalen += 4;
|
||||
|
||||
// length is 4 bytes
|
||||
if (type == REQUEST || type == CANCEL)
|
||||
if (type == REQUEST || type == CANCEL ||
|
||||
type == REJECT)
|
||||
datalen += 4;
|
||||
|
||||
// msg type is 1 byte
|
||||
@ -131,15 +136,18 @@ class Message
|
||||
dos.writeByte(type & 0xFF);
|
||||
|
||||
// Send additional info (piece number)
|
||||
if (type == HAVE || type == REQUEST || type == PIECE || type == CANCEL)
|
||||
if (type == HAVE || type == REQUEST || type == PIECE || type == CANCEL ||
|
||||
type == SUGGEST || type == REJECT || type == ALLOWED_FAST)
|
||||
dos.writeInt(piece);
|
||||
|
||||
// Send additional info (begin/offset)
|
||||
if (type == REQUEST || type == PIECE || type == CANCEL)
|
||||
if (type == REQUEST || type == PIECE || type == CANCEL ||
|
||||
type == REJECT)
|
||||
dos.writeInt(begin);
|
||||
|
||||
// Send additional info (length); for PIECE this is implicit.
|
||||
if (type == REQUEST || type == CANCEL)
|
||||
if (type == REQUEST || type == CANCEL ||
|
||||
type == REJECT)
|
||||
dos.writeInt(length);
|
||||
|
||||
if (type == EXTENSION)
|
||||
@ -173,21 +181,32 @@ class Message
|
||||
case UNINTERESTED:
|
||||
return "UNINTERESTED";
|
||||
case HAVE:
|
||||
return "HAVE(" + piece + ")";
|
||||
return "HAVE(" + piece + ')';
|
||||
case BITFIELD:
|
||||
return "BITFIELD";
|
||||
case REQUEST:
|
||||
return "REQUEST(" + piece + "," + begin + "," + length + ")";
|
||||
return "REQUEST(" + piece + ',' + begin + ',' + length + ')';
|
||||
case PIECE:
|
||||
return "PIECE(" + piece + "," + begin + "," + length + ")";
|
||||
return "PIECE(" + piece + ',' + begin + ',' + length + ')';
|
||||
case CANCEL:
|
||||
return "CANCEL(" + piece + "," + begin + "," + length + ")";
|
||||
return "CANCEL(" + piece + ',' + begin + ',' + length + ')';
|
||||
case PORT:
|
||||
return "PORT(" + piece + ")";
|
||||
return "PORT(" + piece + ')';
|
||||
case EXTENSION:
|
||||
return "EXTENSION(" + piece + ',' + data.length + ')';
|
||||
// fast extensions below here
|
||||
case SUGGEST:
|
||||
return "SUGGEST(" + piece + ')';
|
||||
case HAVE_ALL:
|
||||
return "HAVE_ALL";
|
||||
case HAVE_NONE:
|
||||
return "HAVE_NONE";
|
||||
case REJECT:
|
||||
return "REJECT(" + piece + ',' + begin + ',' + length + ')';
|
||||
case ALLOWED_FAST:
|
||||
return "ALLOWED_FAST(" + piece + ')';
|
||||
default:
|
||||
return "<UNKNOWN>";
|
||||
return "UNKNOWN (" + type + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,11 @@ public class MetaInfo
|
||||
* @param files null for single-file torrent
|
||||
* @param lengths null for single-file torrent
|
||||
* @param announce_list may be null
|
||||
* @param created_by may be null
|
||||
*/
|
||||
MetaInfo(String announce, String name, String name_utf8, List<List<String>> files, List<Long> lengths,
|
||||
int piece_length, byte[] piece_hashes, long length, boolean privateTorrent,
|
||||
List<List<String>> announce_list)
|
||||
List<List<String>> announce_list, String created_by)
|
||||
{
|
||||
this.announce = announce;
|
||||
this.name = name;
|
||||
@ -91,8 +92,8 @@ public class MetaInfo
|
||||
this.privateTorrent = privateTorrent;
|
||||
this.announce_list = announce_list;
|
||||
this.comment = null;
|
||||
this.created_by = null;
|
||||
this.creation_date = 0;
|
||||
this.created_by = created_by;
|
||||
this.creation_date = I2PAppContext.getGlobalContext().clock().now();
|
||||
|
||||
// TODO if we add a parameter for other keys
|
||||
//if (other != null) {
|
||||
@ -156,11 +157,11 @@ public class MetaInfo
|
||||
if (val == null) {
|
||||
this.announce_list = null;
|
||||
} else {
|
||||
this.announce_list = new ArrayList();
|
||||
this.announce_list = new ArrayList<List<String>>();
|
||||
List<BEValue> bl1 = val.getList();
|
||||
for (BEValue bev : bl1) {
|
||||
List<BEValue> bl2 = bev.getList();
|
||||
List<String> sl2 = new ArrayList();
|
||||
List<String> sl2 = new ArrayList<String>();
|
||||
for (BEValue bev2 : bl2) {
|
||||
sl2.add(bev2.getString());
|
||||
}
|
||||
@ -216,7 +217,18 @@ public class MetaInfo
|
||||
|
||||
// BEP 27
|
||||
val = info.get("private");
|
||||
privateTorrent = val != null && val.getString().equals("1");
|
||||
if (val != null) {
|
||||
Object o = val.getValue();
|
||||
// Is it supposed to be a number or a string?
|
||||
// i2psnark does it as a string. BEP 27 doesn't say.
|
||||
// Transmission does numbers. So does libtorrent.
|
||||
// We handle both as of 0.9.9.
|
||||
// We switch to storing as number as of 0.9.14.
|
||||
privateTorrent = "1".equals(o) ||
|
||||
((o instanceof Number) && ((Number) o).intValue() == 1);
|
||||
} else {
|
||||
privateTorrent = false;
|
||||
}
|
||||
|
||||
val = info.get("piece length");
|
||||
if (val == null)
|
||||
@ -250,9 +262,9 @@ public class MetaInfo
|
||||
if (size == 0)
|
||||
throw new InvalidBEncodingException("zero size files list");
|
||||
|
||||
List<List<String>> m_files = new ArrayList(size);
|
||||
List<List<String>> m_files_utf8 = new ArrayList(size);
|
||||
List<Long> m_lengths = new ArrayList(size);
|
||||
List<List<String>> m_files = new ArrayList<List<String>>(size);
|
||||
List<List<String>> m_files_utf8 = new ArrayList<List<String>>(size);
|
||||
List<Long> m_lengths = new ArrayList<Long>(size);
|
||||
long l = 0;
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
{
|
||||
@ -278,7 +290,7 @@ public class MetaInfo
|
||||
if (path_length == 0)
|
||||
throw new InvalidBEncodingException("zero size file path list");
|
||||
|
||||
List<String> file = new ArrayList(path_length);
|
||||
List<String> file = new ArrayList<String>(path_length);
|
||||
Iterator<BEValue> it = path_list.iterator();
|
||||
while (it.hasNext()) {
|
||||
String s = it.next().getString();
|
||||
@ -301,7 +313,7 @@ public class MetaInfo
|
||||
path_list = val.getList();
|
||||
path_length = path_list.size();
|
||||
if (path_length > 0) {
|
||||
file = new ArrayList(path_length);
|
||||
file = new ArrayList<String>(path_length);
|
||||
it = path_list.iterator();
|
||||
while (it.hasNext())
|
||||
file.add(it.next().getString());
|
||||
@ -433,7 +445,7 @@ public class MetaInfo
|
||||
|
||||
/**
|
||||
* The creation date (ms) or zero.
|
||||
* Not available for locally-created torrents.
|
||||
* As of 0.9.19, available for locally-created torrents.
|
||||
* @since 0.9.7
|
||||
*/
|
||||
public long getCreationDate() {
|
||||
@ -506,9 +518,10 @@ public class MetaInfo
|
||||
|
||||
sha1.update(bs, off, length);
|
||||
byte[] hash = sha1.digest();
|
||||
for (int i = 0; i < 20; i++)
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (hash[i] != piece_hashes[20 * piece + i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -517,7 +530,6 @@ public class MetaInfo
|
||||
* @since 0.9.1
|
||||
*/
|
||||
boolean checkPiece(PartialPiece pp) {
|
||||
MessageDigest sha1 = SHA1.getInstance();
|
||||
int piece = pp.getPiece();
|
||||
byte[] hash;
|
||||
try {
|
||||
@ -529,9 +541,10 @@ public class MetaInfo
|
||||
_log.warn("Error checking", ioe);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 20; i++)
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (hash[i] != piece_hashes[20 * piece + i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -565,10 +578,10 @@ public class MetaInfo
|
||||
*/
|
||||
public MetaInfo reannounce(String announce) throws InvalidBEncodingException
|
||||
{
|
||||
Map<String, BEValue> m = new HashMap();
|
||||
Map<String, BEValue> m = new HashMap<String, BEValue>();
|
||||
if (announce != null)
|
||||
m.put("announce", new BEValue(DataHelper.getUTF8(announce)));
|
||||
Map info = createInfoMap();
|
||||
Map<String, BEValue> info = createInfoMap();
|
||||
m.put("info", new BEValue(info));
|
||||
return new MetaInfo(m);
|
||||
}
|
||||
@ -578,12 +591,20 @@ public class MetaInfo
|
||||
*/
|
||||
public synchronized byte[] getTorrentData()
|
||||
{
|
||||
Map m = new HashMap();
|
||||
Map<String, Object> m = new HashMap<String, Object>();
|
||||
if (announce != null)
|
||||
m.put("announce", announce);
|
||||
if (announce_list != null)
|
||||
m.put("announce-list", announce_list);
|
||||
Map info = createInfoMap();
|
||||
// misc. optional top-level stuff
|
||||
if (comment != null)
|
||||
m.put("comment", comment);
|
||||
if (created_by != null)
|
||||
m.put("created by", created_by);
|
||||
if (creation_date != 0)
|
||||
m.put("creation date", creation_date / 1000);
|
||||
|
||||
Map<String, BEValue> info = createInfoMap();
|
||||
m.put("info", info);
|
||||
// don't save this locally, we should only do this once
|
||||
return BEncoder.bencode(m);
|
||||
@ -607,31 +628,44 @@ public class MetaInfo
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Creating new infomap", new Exception());
|
||||
// otherwise we must create it
|
||||
Map info = new HashMap();
|
||||
info.put("name", name);
|
||||
Map<String, BEValue> info = new HashMap<String, BEValue>();
|
||||
info.put("name", new BEValue(DataHelper.getUTF8(name)));
|
||||
if (name_utf8 != null)
|
||||
info.put("name.utf-8", name_utf8);
|
||||
info.put("name.utf-8", new BEValue(DataHelper.getUTF8(name_utf8)));
|
||||
// BEP 27
|
||||
if (privateTorrent)
|
||||
info.put("private", "1");
|
||||
// switched to number in 0.9.14
|
||||
//info.put("private", new BEValue(DataHelper.getUTF8("1")));
|
||||
info.put("private", new BEValue(Integer.valueOf(1)));
|
||||
|
||||
info.put("piece length", Integer.valueOf(piece_length));
|
||||
info.put("pieces", piece_hashes);
|
||||
info.put("piece length", new BEValue(Integer.valueOf(piece_length)));
|
||||
info.put("pieces", new BEValue(piece_hashes));
|
||||
if (files == null)
|
||||
info.put("length", Long.valueOf(length));
|
||||
info.put("length", new BEValue(Long.valueOf(length)));
|
||||
else
|
||||
{
|
||||
List l = new ArrayList();
|
||||
List<BEValue> l = new ArrayList<BEValue>();
|
||||
for (int i = 0; i < files.size(); i++)
|
||||
{
|
||||
Map file = new HashMap();
|
||||
file.put("path", files.get(i));
|
||||
if ( (files_utf8 != null) && (files_utf8.size() > i) )
|
||||
file.put("path.utf-8", files_utf8.get(i));
|
||||
file.put("length", lengths.get(i));
|
||||
l.add(file);
|
||||
Map<String, BEValue> file = new HashMap<String, BEValue>();
|
||||
List<String> fi = files.get(i);
|
||||
List<BEValue> befiles = new ArrayList<BEValue>(fi.size());
|
||||
for (int j = 0; j < fi.size(); j++) {
|
||||
befiles.add(new BEValue(DataHelper.getUTF8(fi.get(j))));
|
||||
}
|
||||
file.put("path", new BEValue(befiles));
|
||||
if ( (files_utf8 != null) && (files_utf8.size() > i) ) {
|
||||
List<String> fiu = files_utf8.get(i);
|
||||
List<BEValue> beufiles = new ArrayList<BEValue>(fiu.size());
|
||||
for (int j = 0; j < fiu.size(); j++) {
|
||||
beufiles.add(new BEValue(DataHelper.getUTF8(fiu.get(j))));
|
||||
}
|
||||
file.put("path.utf-8", new BEValue(beufiles));
|
||||
}
|
||||
file.put("length", new BEValue(lengths.get(i)));
|
||||
l.add(new BEValue(file));
|
||||
}
|
||||
info.put("files", l);
|
||||
info.put("files", new BEValue(l));
|
||||
}
|
||||
|
||||
// TODO if we add the ability for other keys in the first constructor
|
||||
|
@ -31,7 +31,7 @@ import net.i2p.util.SecureFile;
|
||||
*
|
||||
* @since 0.8.2
|
||||
*/
|
||||
class PartialPiece implements Comparable {
|
||||
class PartialPiece implements Comparable<PartialPiece> {
|
||||
|
||||
// we store the piece so we can use it in compareTo()
|
||||
private final Piece piece;
|
||||
@ -108,7 +108,8 @@ class PartialPiece implements Comparable {
|
||||
|
||||
/**
|
||||
* Convert this PartialPiece to a request for the next chunk.
|
||||
* Used by PeerState only.
|
||||
* Used by PeerState only. This depends on the downloaded value
|
||||
* as set by setDownloaded() or read().
|
||||
*/
|
||||
|
||||
public Request getRequest() {
|
||||
@ -128,14 +129,16 @@ class PartialPiece implements Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* How many bytes are good - only valid by setDownloaded()
|
||||
* How many bytes are good - as set by setDownloaded() or read()
|
||||
*/
|
||||
public int getDownloaded() {
|
||||
return this.off;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this before returning a PartialPiece to the PeerCoordinator
|
||||
* Call this if necessary before returning a PartialPiece to the PeerCoordinator.
|
||||
* We do not use a bitmap to track individual chunks received.
|
||||
* Any chunks after a 'hole' will be lost.
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public void setDownloaded(int offset) {
|
||||
@ -191,11 +194,20 @@ class PartialPiece implements Comparable {
|
||||
|
||||
/**
|
||||
* Blocking.
|
||||
* If offset matches the previous downloaded amount
|
||||
* (as set by a previous call to read() or setDownlaoded()),
|
||||
* the downloaded amount will be incremented by len.
|
||||
*
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public void read(DataInputStream din, int off, int len) throws IOException {
|
||||
public void read(DataInputStream din, int offset, int len) throws IOException {
|
||||
if (bs != null) {
|
||||
din.readFully(bs, off, len);
|
||||
din.readFully(bs, offset, len);
|
||||
synchronized (this) {
|
||||
// only works for in-order chunks
|
||||
if (this.off == offset)
|
||||
this.off += len;
|
||||
}
|
||||
} else {
|
||||
// read in fully before synching on raf
|
||||
ByteArray ba;
|
||||
@ -211,8 +223,11 @@ class PartialPiece implements Comparable {
|
||||
synchronized (this) {
|
||||
if (raf == null)
|
||||
createTemp();
|
||||
raf.seek(off);
|
||||
raf.seek(offset);
|
||||
raf.write(tmp);
|
||||
// only works for in-order chunks
|
||||
if (this.off == offset)
|
||||
this.off += len;
|
||||
}
|
||||
if (ba != null)
|
||||
_cache.release(ba, false);
|
||||
@ -295,8 +310,7 @@ class PartialPiece implements Comparable {
|
||||
* then rarest first,
|
||||
* then highest downloaded first
|
||||
*/
|
||||
public int compareTo(Object o) throws ClassCastException {
|
||||
PartialPiece opp = (PartialPiece)o;
|
||||
public int compareTo(PartialPiece opp) {
|
||||
int d = this.piece.compareTo(opp.piece);
|
||||
if (d != 0)
|
||||
return d;
|
||||
|
@ -28,6 +28,8 @@ import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
@ -37,7 +39,7 @@ import net.i2p.util.Log;
|
||||
|
||||
import org.klomp.snark.bencode.BEValue;
|
||||
|
||||
public class Peer implements Comparable
|
||||
public class Peer implements Comparable<Peer>
|
||||
{
|
||||
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(Peer.class);
|
||||
// Identifying property, the peer id of the other side.
|
||||
@ -55,12 +57,12 @@ public class Peer implements Comparable
|
||||
private DataOutputStream dout;
|
||||
|
||||
/** running counters */
|
||||
private long downloaded;
|
||||
private long uploaded;
|
||||
private final AtomicLong downloaded = new AtomicLong();
|
||||
private final AtomicLong uploaded = new AtomicLong();
|
||||
|
||||
// Keeps state for in/out connections. Non-null when the handshake
|
||||
// was successful, the connection setup and runs
|
||||
PeerState state;
|
||||
volatile PeerState state;
|
||||
|
||||
/** shared across all peers on this torrent */
|
||||
MagnetState magnetState;
|
||||
@ -68,22 +70,24 @@ public class Peer implements Comparable
|
||||
private I2PSocket sock;
|
||||
|
||||
private boolean deregister = true;
|
||||
private static long __id;
|
||||
private long _id;
|
||||
private static final AtomicLong __id = new AtomicLong();
|
||||
private final long _id;
|
||||
private final AtomicBoolean _disconnected = new AtomicBoolean();
|
||||
|
||||
final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
|
||||
final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long
|
||||
private long uploaded_old[] = {-1,-1,-1};
|
||||
private long downloaded_old[] = {-1,-1,-1};
|
||||
|
||||
// bytes per bt spec: 0011223344556677
|
||||
static final long OPTION_EXTENSION = 0x0000000000100000l;
|
||||
static final long OPTION_FAST = 0x0000000000000004l;
|
||||
static final long OPTION_DHT = 0x0000000000000001l;
|
||||
// bytes per bt spec: 0011223344556677
|
||||
private static final long OPTION_EXTENSION = 0x0000000000100000l;
|
||||
private static final long OPTION_FAST = 0x0000000000000004l;
|
||||
//private static final long OPTION_DHT = 0x0000000000000001l;
|
||||
/** we use a different bit since the compact format is different */
|
||||
/* no, let's use an extension message
|
||||
static final long OPTION_I2P_DHT = 0x0000000040000000l;
|
||||
*/
|
||||
static final long OPTION_AZMP = 0x1000000000000000l;
|
||||
//private static final long OPTION_AZMP = 0x1000000000000000l;
|
||||
private long options;
|
||||
|
||||
/**
|
||||
@ -98,7 +102,7 @@ public class Peer implements Comparable
|
||||
this.my_id = my_id;
|
||||
this.infohash = infohash;
|
||||
this.metainfo = metainfo;
|
||||
_id = ++__id;
|
||||
_id = __id.incrementAndGet();
|
||||
//_log.debug("Creating a new peer with " + peerID.toString(), new Exception("creating"));
|
||||
}
|
||||
|
||||
@ -123,7 +127,7 @@ public class Peer implements Comparable
|
||||
|
||||
byte[] id = handshake(in, out);
|
||||
this.peerID = new PeerID(id, sock.getPeerDestination());
|
||||
_id = ++__id;
|
||||
_id = __id.incrementAndGet();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Creating a new peer " + peerID.toString(), new Exception("creating " + _id));
|
||||
}
|
||||
@ -190,9 +194,8 @@ public class Peer implements Comparable
|
||||
* Compares the PeerIDs.
|
||||
* @deprecated unused?
|
||||
*/
|
||||
public int compareTo(Object o)
|
||||
public int compareTo(Peer p)
|
||||
{
|
||||
Peer p = (Peer)o;
|
||||
int rv = peerID.compareTo(p.peerID);
|
||||
if (rv == 0) {
|
||||
if (_id > p._id) return 1;
|
||||
@ -214,9 +217,11 @@ public class Peer implements Comparable
|
||||
*
|
||||
* If the given BitField is non-null it is send to the peer as first
|
||||
* message.
|
||||
*
|
||||
* @param uploadOnly if we are complete with skipped files, i.e. a partial seed
|
||||
*/
|
||||
public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField bitfield, MagnetState mState)
|
||||
{
|
||||
public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField bitfield,
|
||||
MagnetState mState, boolean uploadOnly) {
|
||||
if (state != null)
|
||||
throw new IllegalStateException("Peer already started");
|
||||
|
||||
@ -272,17 +277,9 @@ public class Peer implements Comparable
|
||||
int metasize = metainfo != null ? metainfo.getInfoBytes().length : -1;
|
||||
boolean pexAndMetadata = metainfo == null || !metainfo.isPrivate();
|
||||
boolean dht = util.getDHT() != null;
|
||||
out.sendExtension(0, ExtensionHandler.getHandshake(metasize, pexAndMetadata, dht));
|
||||
out.sendExtension(0, ExtensionHandler.getHandshake(metasize, pexAndMetadata, dht, uploadOnly));
|
||||
}
|
||||
|
||||
// Old DHT PORT message
|
||||
//if ((options & OPTION_I2P_DHT) != 0 && util.getDHT() != null) {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Peer supports DHT, sending PORT message");
|
||||
// int port = util.getDHT().getPort();
|
||||
// out.sendPort(port);
|
||||
//}
|
||||
|
||||
// Send our bitmap
|
||||
if (bitfield != null)
|
||||
s.out.sendBitfield(bitfield);
|
||||
@ -294,7 +291,7 @@ public class Peer implements Comparable
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Start running the reader with " + toString());
|
||||
// Use this thread for running the incomming connection.
|
||||
// Use this thread for running the incoming connection.
|
||||
// The outgoing connection creates its own Thread.
|
||||
out.startup();
|
||||
Thread.currentThread().setName("Snark reader from " + peerID);
|
||||
@ -335,6 +332,9 @@ public class Peer implements Comparable
|
||||
dout.write("BitTorrent protocol".getBytes("UTF-8"));
|
||||
// Handshake write - options
|
||||
long myOptions = OPTION_EXTENSION;
|
||||
// we can't handle HAVE_ALL or HAVE_NONE if we don't know the number of pieces
|
||||
if (metainfo != null)
|
||||
myOptions |= OPTION_FAST;
|
||||
// FIXME get util here somehow
|
||||
//if (util.getDHT() != null)
|
||||
// myOptions |= OPTION_I2P_DHT;
|
||||
@ -382,15 +382,15 @@ public class Peer implements Comparable
|
||||
if (options != 0) {
|
||||
// send them something in runConnection() above
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString());
|
||||
_log.debug("Peer supports options 0x" + Long.toHexString(options) + ": " + toString());
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
/** @since 0.8.4 */
|
||||
public long getOptions() {
|
||||
return options;
|
||||
/** @since 0.9.21 */
|
||||
public boolean supportsFast() {
|
||||
return (options & OPTION_FAST) != 0;
|
||||
}
|
||||
|
||||
/** @since 0.8.4 */
|
||||
@ -457,6 +457,8 @@ public class Peer implements Comparable
|
||||
|
||||
void disconnect()
|
||||
{
|
||||
if (!_disconnected.compareAndSet(false, true))
|
||||
return;
|
||||
PeerState s = state;
|
||||
if (s != null)
|
||||
{
|
||||
@ -476,9 +478,11 @@ public class Peer implements Comparable
|
||||
PeerConnectionIn in = s.in;
|
||||
if (in != null)
|
||||
in.disconnect();
|
||||
PeerConnectionOut out = s.out;
|
||||
if (out != null)
|
||||
out.disconnect();
|
||||
// this is blocking in streaming, so do this after closing the socket
|
||||
// so it won't really block
|
||||
//PeerConnectionOut out = s.out;
|
||||
//if (out != null)
|
||||
// out.disconnect();
|
||||
PeerListener pl = s.listener;
|
||||
if (pl != null)
|
||||
pl.disconnected(this);
|
||||
@ -492,6 +496,13 @@ public class Peer implements Comparable
|
||||
_log.warn("Error disconnecting " + toString(), ioe);
|
||||
}
|
||||
}
|
||||
if (s != null) {
|
||||
// this is blocking in streaming, so do this after closing the socket
|
||||
// so it won't really block
|
||||
PeerConnectionOut out = s.out;
|
||||
if (out != null)
|
||||
out.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -604,7 +615,7 @@ public class Peer implements Comparable
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public void downloaded(int size) {
|
||||
downloaded += size;
|
||||
downloaded.addAndGet(size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -612,7 +623,7 @@ public class Peer implements Comparable
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public void uploaded(int size) {
|
||||
uploaded += size;
|
||||
uploaded.addAndGet(size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,7 +632,7 @@ public class Peer implements Comparable
|
||||
*/
|
||||
public long getDownloaded()
|
||||
{
|
||||
return downloaded;
|
||||
return downloaded.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -630,7 +641,7 @@ public class Peer implements Comparable
|
||||
*/
|
||||
public long getUploaded()
|
||||
{
|
||||
return uploaded;
|
||||
return uploaded.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -638,8 +649,8 @@ public class Peer implements Comparable
|
||||
*/
|
||||
public void resetCounters()
|
||||
{
|
||||
downloaded = 0;
|
||||
uploaded = 0;
|
||||
downloaded.set(0);
|
||||
uploaded.set(0);
|
||||
}
|
||||
|
||||
public long getInactiveTime() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user