forked from I2P_Developers/i2p.i2p
Compare commits
2155 Commits
i2p-0.9.17
...
i2p-0.9.31
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c76b87fba | |||
| bbe3a71d2c | |||
| 9d1097b467 | |||
| 8beb75be50 | |||
|
|
80c55c150f | ||
|
|
82806099a7 | ||
| 903f46f3a8 | |||
| d99a699839 | |||
|
|
9f15ae6e56 | ||
|
|
26bc83c51b | ||
|
|
5dd5a99de5 | ||
|
|
ac75327a78 | ||
|
|
2f48af517e | ||
|
|
e284675e5a | ||
|
|
674f523cba | ||
|
|
2bfe27d217 | ||
|
|
fe2387e4f0 | ||
|
|
30eb089623 | ||
|
|
ee1112cca7 | ||
|
|
a39fb3d7c2 | ||
|
|
0feb16d57b | ||
|
|
b8f5c956e6 | ||
| 70393fd2d9 | |||
| d4a139f215 | |||
| 0b85bffeff | |||
| 5ddb4edd14 | |||
|
|
d2da262374 | ||
|
|
3c19bb4ec5 | ||
|
|
123c0de700 | ||
|
|
19fcb9e5b9 | ||
|
|
281534b0b0 | ||
|
|
4fff74793b | ||
| 7d62c43209 | |||
| 00388675f1 | |||
| 4ddca951f2 | |||
| 2abaa4a39b | |||
| 402a2af898 | |||
|
|
4e8ed909e3 | ||
|
|
5c670fc57f | ||
|
|
e83d31f749 | ||
|
|
d8831151fe | ||
|
|
87d6c302e6 | ||
|
|
afec920bee | ||
|
|
873b0b0f19 | ||
|
|
96c73e7fcb | ||
|
|
56f6a68ef3 | ||
|
|
7cd7f01db9 | ||
|
|
1650cbe8de | ||
|
|
dc46f00a35 | ||
|
|
d2edce845a | ||
|
|
bd84ba2d5c | ||
|
|
bd74b22b02 | ||
| c768b8f8d7 | |||
|
|
56c0fbeebe | ||
|
|
5bc9d0af52 | ||
|
|
12cbbfbac7 | ||
|
|
4aa4ff738a | ||
|
|
3d535a2282 | ||
|
|
36030ae180 | ||
|
|
e21479a164 | ||
| 32efa2e509 | |||
|
|
8216b68ee1 | ||
|
|
3e4318cca6 | ||
|
|
cf7a6041b3 | ||
| 25c709afe2 | |||
| 58b38b283f | |||
| 931d7a95bd | |||
|
|
d771cc6e37 | ||
|
|
e21a57a1fc | ||
|
|
1ede0c8b2f | ||
|
|
57f3b89eed | ||
|
|
9eedb5c732 | ||
|
|
4964b1165f | ||
|
|
bd1ccba960 | ||
|
|
3334d9f737 | ||
|
|
135920a9bb | ||
|
|
c0742b5cf3 | ||
|
|
163023ecc2 | ||
|
|
791bc9a84f | ||
|
|
c91f942194 | ||
|
|
66385c06ae | ||
|
|
6fe55529d6 | ||
| 4c6af7cdca | |||
|
|
5e8730a616 | ||
|
|
6acca28969 | ||
|
|
017f66a342 | ||
|
|
ff400c9448 | ||
|
|
b28cc94a4a | ||
|
|
4da95af45a | ||
|
|
a9bf1e2969 | ||
|
|
d50c12dc7d | ||
| 5361571c15 | |||
| 13d9322d81 | |||
| d35f260f15 | |||
| 7338b79ef1 | |||
|
|
edda87d53e | ||
| de0a5c7094 | |||
|
|
008f421377 | ||
|
|
6821e13820 | ||
|
|
fa73b481e6 | ||
|
|
63581d32de | ||
|
|
0db637ed5a | ||
|
|
62b3e19217 | ||
|
|
2b82312b77 | ||
| 81b8b18581 | |||
| 769cb40b79 | |||
| 81026c2871 | |||
| dc33ad101a | |||
|
|
b7baeddc7c | ||
|
|
e6b968e48c | ||
|
|
96bdfb3a63 | ||
|
|
7002c683ab | ||
|
|
ae7c2f6e5f | ||
| b8c97a1d7a | |||
| a5551c1be3 | |||
| 7d129215cf | |||
| 777d2fc0f0 | |||
| 7f45e97335 | |||
|
|
feee22e389 | ||
|
|
208372ed9e | ||
|
|
6fd66c9396 | ||
|
|
e8c28ad42c | ||
|
|
5caefb5ea9 | ||
| ac788d973f | |||
| e973185be1 | |||
| 040af114e1 | |||
|
|
6f60d642af | ||
|
|
8a5967f592 | ||
|
|
a929b5c683 | ||
|
|
e32d4b15e8 | ||
|
|
67b3c46758 | ||
|
|
7de815bd90 | ||
|
|
0aae97162e | ||
|
|
ac31a1319b | ||
|
|
e453ea48e1 | ||
|
|
8f04aa70cb | ||
|
|
d7d13d1a4f | ||
|
|
6b056ce6e0 | ||
| b340f4a17c | |||
| 93cb2a0513 | |||
| 610af51e95 | |||
| efd7d651cc | |||
| d139892ae0 | |||
| 45f3695f9d | |||
| 3e354f2f1a | |||
| b0514cc564 | |||
| 3718c73341 | |||
| cd76457128 | |||
| f3d931d090 | |||
| ffb3e27c0f | |||
| 8d6ca6431d | |||
| 920b14212f | |||
| 1e9c68859e | |||
|
|
e390e67aee | ||
| d27d060322 | |||
| baa314d71f | |||
| d98c3d8f71 | |||
| 5e497f790d | |||
| 3dbbc2943f | |||
| 925caccb57 | |||
| a21e027403 | |||
| 4dec3657b0 | |||
| 06f78d7cfe | |||
| 6901914640 | |||
| 75db7fa196 | |||
| f8ea882f99 | |||
| dd0153e29a | |||
| 9dd146680d | |||
| 5fa6583a4e | |||
|
|
48661361fa | ||
|
|
4747172059 | ||
|
|
f541dbe042 | ||
|
|
a3e146a814 | ||
|
|
fa6fc84bf8 | ||
|
|
a0911a43dd | ||
|
|
b6c6a5d696 | ||
|
|
5353fd986e | ||
|
|
3f40af54d1 | ||
|
|
9e8d4fbe21 | ||
|
|
cb3326fa42 | ||
|
|
123473439c | ||
|
|
c12312f523 | ||
| dd8f7638c5 | |||
| 4edc4077f8 | |||
| 0d3b1fa490 | |||
| 828b0954a3 | |||
| ec82912085 | |||
| 021067dab9 | |||
| bfc04178a6 | |||
| f390831835 | |||
| 5eefb8b222 | |||
| c06e320f99 | |||
| b810b79a44 | |||
| 3cc0122af4 | |||
| 48fb12ebeb | |||
| 82554b943e | |||
| 04e0cfe020 | |||
| ed590cd6f5 | |||
| c1991241e4 | |||
| b503f03bd6 | |||
| cff8eafc43 | |||
| a0b2f5738a | |||
| b335ded1d2 | |||
| 0a2097a238 | |||
| 1ab67de677 | |||
| 47277063e4 | |||
| ca6ce37a0b | |||
| a00f11d5b7 | |||
| 13ad5d72ae | |||
| b9a7a76174 | |||
| a8ae2ce955 | |||
| de5661ef1b | |||
| e4da3b0f3b | |||
| 95b6bd36e5 | |||
| 05aef9bd59 | |||
| fda673038f | |||
| 24801553d6 | |||
| 43c3a14745 | |||
| 4b722c9b7f | |||
| 1150b4cd73 | |||
| e7cfb2d6fe | |||
| ad810de747 | |||
| b57d7c699f | |||
| ba825e61d5 | |||
| aea20a552e | |||
| 0703a29562 | |||
| db0381d6b1 | |||
| a9be26d2bc | |||
| db5ab0b9b8 | |||
| 072d990279 | |||
| 6b4f665f34 | |||
| 48a055d462 | |||
| 9146f3c7e1 | |||
| 1fe9acefe2 | |||
| 359b4570e4 | |||
| 1c720a0fda | |||
| d1fdf14911 | |||
| 6fbeef5f8c | |||
| 6ef6106336 | |||
| 23ee40d990 | |||
| 4e236fc5ab | |||
| d573910b7a | |||
| da00b95599 | |||
| e20310d257 | |||
|
|
74151b06ef | ||
|
|
de7a4ba55c | ||
|
|
5ddeeec9ea | ||
|
|
1f7042a68e | ||
|
|
a65722f3e8 | ||
|
|
964dacd907 | ||
|
|
25b03979d5 | ||
|
|
6151480ee6 | ||
|
|
97fa5d9921 | ||
|
|
83c9dc7437 | ||
|
|
4bf0147198 | ||
|
|
d7e5aaf919 | ||
|
|
10a021f5fc | ||
|
|
20df511401 | ||
|
|
73708041e8 | ||
| b71aafbb28 | |||
| 319ce9b065 | |||
| 87cff00b99 | |||
| f38ee48ca3 | |||
| ec6c24429a | |||
| 15915afeb8 | |||
| b72085bcf3 | |||
| 5f96067c22 | |||
| 61e4e2a052 | |||
| f7cdf221eb | |||
| 69ad95710a | |||
| 920572d3bc | |||
| d3abbe86e9 | |||
| 3631efa567 | |||
| a6e62afc1f | |||
| 8bfb3649dd | |||
| 45abf6575c | |||
| 7fb82da7ff | |||
| e995a4cf92 | |||
| 2de25ca453 | |||
| 8d928eadba | |||
| e03c25e397 | |||
| b695293070 | |||
| c09bfa0a26 | |||
| f420a99b6f | |||
| 33b1851317 | |||
| 3c735eaf96 | |||
| 3f452c5acb | |||
| 380f55a0e8 | |||
| 8a89b3da29 | |||
| f2ae1bfe09 | |||
| 17b781c1b4 | |||
| 68fb3f42a8 | |||
| fc8c193f37 | |||
| c949d776be | |||
| e29e3e2fd3 | |||
| e01c443fa2 | |||
|
|
50450ecba6 | ||
|
|
44c0d9357b | ||
|
|
42ba5fa509 | ||
|
|
24b2bb8e3f | ||
|
|
026a9cf026 | ||
|
|
87c8031e5a | ||
|
|
bff3f0436c | ||
|
|
bfe8c65628 | ||
|
|
a22bf6b4a4 | ||
|
|
c4e7b1a799 | ||
|
|
232d0b5e77 | ||
|
|
82095d9786 | ||
|
|
f68967c5f2 | ||
|
|
9898a4a930 | ||
|
|
092881acc4 | ||
|
|
b1ed295e26 | ||
| 2d8f0c2956 | |||
| f0241d4a1c | |||
| a11bd7cbe7 | |||
| 36ec4de9c7 | |||
| 843b66d61e | |||
| afb87cd75c | |||
| aa098ac800 | |||
| bbbbfe2417 | |||
| 9ab55ec368 | |||
| a85546534e | |||
| 83c786a5fd | |||
| 50d735b126 | |||
| da893452ea | |||
| 6306799a4b | |||
| 82d812c25c | |||
| 890ad257e1 | |||
| 7cb5dab67f | |||
| 1cf6030646 | |||
| 36fd93da0d | |||
| 5483306d21 | |||
| 1f228a3f85 | |||
| 12cc7b3a3b | |||
| 61fd242938 | |||
| 78da3b9785 | |||
| e0e06d73eb | |||
| 112fa503e6 | |||
| 9dab3b0dfe | |||
| 82064760d5 | |||
| bd1354f95b | |||
| fb74f41692 | |||
| 5db89d8743 | |||
| b970912cc1 | |||
| d196047382 | |||
| eefb36cb99 | |||
| dc5bfb224d | |||
| e461e8fb4f | |||
| 8bb114e9c4 | |||
| f77fc52ca7 | |||
| 1a28a2af23 | |||
| d9c6360e0a | |||
| 8137661751 | |||
| c66559ff84 | |||
| e47c628891 | |||
| 7b0a5bcd5a | |||
| 6e7dedba81 | |||
| 83e356140d | |||
| b66c7802e7 | |||
| 7311cf33b7 | |||
| 60c93f1e1c | |||
| a36083ab18 | |||
|
|
6308038a08 | ||
|
|
e141abb5de | ||
|
|
94c6496f9d | ||
|
|
d360ba4817 | ||
|
|
cca3f57373 | ||
|
|
57e51ab8c5 | ||
|
|
93511c0e61 | ||
| 7cae467b59 | |||
| 2df64cd098 | |||
|
|
0a0757a69f | ||
|
|
14bacc272e | ||
|
|
2bc5630832 | ||
|
|
ecb9726ba4 | ||
|
|
894186e975 | ||
|
|
053ebd7079 | ||
|
|
fabc57b57a | ||
|
|
04b9b202e5 | ||
|
|
acec99ff43 | ||
|
|
e81a01d3e8 | ||
|
|
7101fb0997 | ||
|
|
6b7ac9fba6 | ||
|
|
0badcf63aa | ||
|
|
bd69499f8f | ||
|
|
23f835781c | ||
|
|
5dd6f2d06b | ||
|
|
7f9a211242 | ||
| ca440a50fe | |||
| 994b51b5b1 | |||
| fc0ddb0193 | |||
| f0e6baad27 | |||
| 6ad4cb0928 | |||
| 91163948b5 | |||
| e16cf2ce51 | |||
| 307a03f0ed | |||
| b63d44b226 | |||
| 57be0df858 | |||
| 6843950bdc | |||
| 134cbd46e4 | |||
|
|
91007735a1 | ||
|
|
14ca463499 | ||
| a7492269fb | |||
| 074c630ac6 | |||
| f902a63144 | |||
| ffcd2d4517 | |||
| dd400bb14b | |||
| 63a2a6da08 | |||
| 3846e08e68 | |||
| e625e67b5d | |||
| 0819857b86 | |||
| fbbfd8acf0 | |||
| 95fb2df609 | |||
| c1baee64d3 | |||
| ce47d4ea68 | |||
| 14a839ebba | |||
| 636badcec2 | |||
| 6093f26fb6 | |||
| 4615fce28e | |||
| 328f544de1 | |||
| 0c76201bd9 | |||
| 0a1cd20585 | |||
| 26a9e8bd89 | |||
| f5e8220c8b | |||
| b7c7e02518 | |||
| 7eadc3df6f | |||
| 2f3f01c5c7 | |||
| 5d7546598e | |||
| 434e3badd6 | |||
| 541e9e6dc0 | |||
| 8a3a725730 | |||
| 74cd5cee20 | |||
| b78b3cb942 | |||
| 62b5b49b02 | |||
| 7734d3dd65 | |||
| 27724a809f | |||
| 1d6fc40d59 | |||
| 176ecaa9f1 | |||
| 42efed578a | |||
| f461d4881d | |||
| 5be077e25d | |||
| 5b31540fe8 | |||
| ec94a6eca3 | |||
| 04321e6af3 | |||
| 25fd488db0 | |||
| 850f1504f7 | |||
| 2318a2b319 | |||
| 8d494ad162 | |||
| 5a87c232ea | |||
| f6778c573a | |||
| ffb3a75813 | |||
| e3435dce10 | |||
| 497d08845c | |||
| cc6cd9e402 | |||
| 64f5fed05a | |||
| 1d280156a2 | |||
| 08f7e5d6a8 | |||
| b72b768945 | |||
| 89733251d4 | |||
| 8146f6fdb6 | |||
| 625e992c91 | |||
| 62064da081 | |||
| 86c0fe327b | |||
| bbb921806e | |||
| fdff5ecd43 | |||
| 97af7d0622 | |||
|
|
11579b9818 | ||
|
|
01cfb7b241 | ||
| b0bba18f33 | |||
| 70902bd279 | |||
| cd4d5a39bf | |||
| 7a1a1d5b93 | |||
| 66c2664b91 | |||
| 68e5fd6d08 | |||
| 37d3204e43 | |||
| 784566a7cb | |||
| 126850626c | |||
| 42cbc1e9ac | |||
| 1a46d9373d | |||
| cd5d5ee23d | |||
| 16a551f7ce | |||
| 75d599e061 | |||
| efd953f3d4 | |||
| 3ac8e5f54f | |||
| 0108c1c290 | |||
| a8976d25e3 | |||
| 6a72c2957b | |||
| f69c0998ea | |||
| 35548ff9be | |||
| 6ed329db78 | |||
| 2c65173bec | |||
| 6acc23af00 | |||
| d7a84c88cd | |||
| aeeee0e5c4 | |||
| c3181d8561 | |||
| 24ecc858f1 | |||
| e5bcfe4207 | |||
| e614b0996d | |||
| b559b412aa | |||
| cd775fa38d | |||
| ab064fd31e | |||
| 08062aaf64 | |||
|
|
e74479317d | ||
| c9c29520b4 | |||
| 81bbf554e8 | |||
| 26a24a98ed | |||
| e8de1daf65 | |||
| 11e86110e7 | |||
| f42d76b4b4 | |||
| e379ca6c54 | |||
| 5d0b35d53a | |||
| 8c71b883bb | |||
| 843351956e | |||
| 7197d22f2a | |||
| b77c4c67a1 | |||
| 62bc616ada | |||
| 9e8251fb9f | |||
| 6ff9483e07 | |||
| 484a3903ca | |||
| 916fc96654 | |||
| 75345f4da1 | |||
| e603437500 | |||
| d49a778b68 | |||
| 95ae86d962 | |||
| 51e35eb572 | |||
| 4f0cae59c2 | |||
| 886dbf1172 | |||
| 04392069a6 | |||
| 78acf707dc | |||
| 08d1ea89bf | |||
| 2b6fd49a53 | |||
| 3063e37cbd | |||
| d2569fa446 | |||
| 8a8452290c | |||
| d2f7b65282 | |||
| 80966d60c1 | |||
| 85223303f2 | |||
| 0860bd3736 | |||
| b53bf7844b | |||
| 75514ddd87 | |||
| 35642e2661 | |||
| c24ddf5deb | |||
| f436fd08ed | |||
| dc523b78d4 | |||
| 06a599b4e7 | |||
| 27cd1a6a6e | |||
| b6521ed884 | |||
| 71f7c712cd | |||
| f5f411b62f | |||
| d367149048 | |||
| 1bd5ebd8ec | |||
| 534609e83a | |||
| 082a5d3c0f | |||
| cee3ebbb23 | |||
| 9b27251473 | |||
| 022479aff9 | |||
| adcee462e3 | |||
| 7d070e6caf | |||
| dcdf3e197c | |||
| 6b5b3617d4 | |||
| be9f7dbf6e | |||
| 38c9cb98a9 | |||
| d8d0414ec4 | |||
| a7870bbd5a | |||
| 19370a36a2 | |||
| 5998587c52 | |||
| 778ce71ea4 | |||
| 72105e218d | |||
| 1af23a4106 | |||
| 6b7d22c211 | |||
| 40b41b0dc5 | |||
| db8a3d5b90 | |||
| 011d08b172 | |||
| 124c2b5ce3 | |||
| 1e375c6de9 | |||
| cc4f63be12 | |||
| 597231bed9 | |||
| 98e3ca47e6 | |||
| a46a0b1b32 | |||
| d4f786c902 | |||
| b123720fa3 | |||
| 1376237e08 | |||
| 78b7385281 | |||
| 4ab727acbd | |||
| 32e1c9617e | |||
| fb323cef69 | |||
| cc179b488d | |||
| 2fd0ed1e74 | |||
| afa5a193a7 | |||
| b0789d45f3 | |||
| be5fdea5e1 | |||
| 268953e19f | |||
| 8cc03c265f | |||
| 47a0df769e | |||
| ff2d5badc9 | |||
| bcaf837da8 | |||
| 0d46c06843 | |||
| cdab6f8b76 | |||
| b21b953ef2 | |||
| 0d5cf46625 | |||
|
|
f7db737c1f | ||
|
|
6512a9eb11 | ||
| 9c0ae14609 | |||
| 5fcafb6434 | |||
| 5763d73dda | |||
| cd4218e523 | |||
| f592f2234b | |||
| c73a4a7983 | |||
|
|
3e96a24fb8 | ||
|
|
01902de200 | ||
|
|
e8e42a0b9d | ||
|
|
5368da2632 | ||
| a1fd8f49d7 | |||
| a213799dac | |||
| b925f517d2 | |||
| 767476ea51 | |||
| 37ebf04bb5 | |||
| 7f2bd164db | |||
| 77014843fb | |||
|
|
ddf332e779 | ||
|
|
e01fe689d0 | ||
|
|
c586970128 | ||
|
|
f1d56a488a | ||
|
|
5f62bf3e62 | ||
|
|
3471950f6f | ||
|
|
0333fb6e22 | ||
|
|
e34eaa351e | ||
|
|
03de374b07 | ||
|
|
6d4f8fd471 | ||
|
|
b38f3b56f8 | ||
| 3baa08a3bb | |||
| 896af2c5d2 | |||
| 2c3311b471 | |||
| 2506f6b143 | |||
| c9b4ab5a13 | |||
| 08fad38782 | |||
| ba8b2df473 | |||
| b819c0334a | |||
| 009f6cce6e | |||
| 4ee66c8218 | |||
| e6f111c5fc | |||
| e146480401 | |||
| e7f82c88f1 | |||
| 9ba8f53ec7 | |||
|
|
47f0bbb93a | ||
|
|
9a9144321d | ||
| 2113946ed0 | |||
| cad7953ef6 | |||
| 1fea327eff | |||
| 16a5295140 | |||
| d84b0e4455 | |||
| bb8e050434 | |||
| e27af374b0 | |||
| 471ff5b939 | |||
| bfbd159706 | |||
| aa8fd85d65 | |||
| bc6583fe57 | |||
| 249e6f0eea | |||
| 7471d04526 | |||
| 389eba23cb | |||
| 63272d3cfc | |||
|
|
78d0a54e96 | ||
| 280ca2cf2f | |||
|
|
f564d4dc22 | ||
| 126a4d8443 | |||
| 38b930cd03 | |||
| 2eb89e938a | |||
| 34c611d340 | |||
| d4ea7dc416 | |||
| 1583f35fe4 | |||
| d7e1f62db4 | |||
|
|
e86092b3e0 | ||
|
|
ed3120956c | ||
| dbd1ae0dfb | |||
| 6f0fde092b | |||
| 7213be43b2 | |||
| d0594ebc77 | |||
| faebe8ab7e | |||
|
|
5cb285b034 | ||
|
|
e16760d4d0 | ||
|
|
3266907346 | ||
|
|
5439ff2195 | ||
|
|
7249b643ac | ||
|
|
efcf294670 | ||
|
|
147a7e4468 | ||
|
|
e969213451 | ||
|
|
03e188b57a | ||
| 8807787b10 | |||
| f653b03288 | |||
| 498280b56d | |||
| 6b8cb54466 | |||
| 0e941625cf | |||
| 2a739f593f | |||
| d48f70c2fe | |||
| f4d4ca0adf | |||
| bb8b3ebe8c | |||
| e518e670f2 | |||
|
|
6b7db094a9 | ||
|
|
9d3dec8577 | ||
|
|
797ee21024 | ||
|
|
e485752546 | ||
|
|
c9728fe2ef | ||
|
|
206718f1e8 | ||
|
|
31b480a68e | ||
|
|
1a335321b2 | ||
|
|
96fc02de5c | ||
|
|
804011d18d | ||
|
|
f95100a1ff | ||
|
|
bbc2454f36 | ||
|
|
62437acf66 | ||
|
|
9cbcf5baa7 | ||
|
|
63260aac59 | ||
|
|
c5432a2098 | ||
| 3afe04d5e9 | |||
| 101d0691f0 | |||
| 18b61e7036 | |||
| 86a35f1a13 | |||
| d6638f3e00 | |||
| f9bd4952f4 | |||
| edbeac9c7b | |||
| 97fca96861 | |||
| 702e1c5a78 | |||
| ea38672159 | |||
| 2d08889977 | |||
|
|
b316315c61 | ||
| ab3dbd5880 | |||
|
|
61be475044 | ||
|
|
29befb44cc | ||
| 6b578dfd8c | |||
| 8bb6922e80 | |||
| 99a5b10ea6 | |||
| bf1fa061e3 | |||
| 16cee2ad56 | |||
| bb468ad38f | |||
| 05012a91ed | |||
| 5d93ca19f8 | |||
| 7d11ec2f08 | |||
|
|
0f6336052a | ||
| 62296222e9 | |||
| 70f9cb1b19 | |||
| ecafcddddb | |||
| dd50b1487b | |||
|
|
c2f35c0d29 | ||
|
|
4fd0261efa | ||
| 390b2d409c | |||
| 196cf48372 | |||
| 8c1f7a4a39 | |||
| 75d6df7789 | |||
| 16ff3e3def | |||
| 0839b46c8d | |||
| cdafab2734 | |||
| 13685484f6 | |||
| cb2790bc62 | |||
| 17542400b9 | |||
| 7a49b09b97 | |||
| 33629d0744 | |||
|
|
6bfd39d5c0 | ||
|
|
8e391444b4 | ||
|
|
a945cabf11 | ||
|
|
4634debe21 | ||
|
|
d0456098e2 | ||
|
|
a3c9887fe5 | ||
|
|
327f36d022 | ||
|
|
8eeb902467 | ||
|
|
61e54cf52e | ||
|
|
50291233a1 | ||
|
|
edb3ffcf45 | ||
|
|
e34f0443bc | ||
|
|
cb0147a798 | ||
|
|
a7f789f069 | ||
|
|
66544f41f2 | ||
|
|
82c55e6008 | ||
|
|
1ad69e7127 | ||
|
|
6470f2d983 | ||
|
|
709ccf6c22 | ||
| 2fe1f97ee0 | |||
| 30ecdedf1f | |||
| efdb296468 | |||
| 43f7897027 | |||
| d8e15dbbc5 | |||
| f3610bc285 | |||
| 6bdf25bc3d | |||
| a2b2c19cbf | |||
| 3e09413e0a | |||
| 139f386fb8 | |||
| 9128c79e05 | |||
| 7ae1483cb3 | |||
| c3f5c04bea | |||
| 2e154881ef | |||
| f2239ba7d1 | |||
| 5067b00058 | |||
| c2e486f72c | |||
| fbeca5ed80 | |||
| d885e00c64 | |||
| 52c9bf6d80 | |||
| 03adda3bde | |||
| da62a1114c | |||
| 13d3730fd9 | |||
| fb5ef83009 | |||
| 94056f68e9 | |||
| 9f31b1fe97 | |||
|
|
414522f8be | ||
|
|
91c8e5cf7f | ||
| a2873c42bc | |||
| 967074c2d6 | |||
| f35eaaf194 | |||
| 6a71c23fd4 | |||
| fc8b72768a | |||
|
|
03887826e8 | ||
| 0ac83bd7c1 | |||
| 2a34d1c44a | |||
| 799d90e1b5 | |||
| f72753f3eb | |||
| d97908b430 | |||
| 2fb8faa166 | |||
| e016c87fba | |||
| 75dd22510b | |||
| 55de82bb50 | |||
| 4f262f6140 | |||
| 34e390909e | |||
| 9b726a8963 | |||
| a0ba623061 | |||
| 9ca8a7752a | |||
| a4265a23ba | |||
| b57b43247d | |||
| 436fee9200 | |||
| 0067c8d1bd | |||
| 0d19fe44c2 | |||
| 4d2c227b0d | |||
| 1a8847d177 | |||
| e9cf4c21b7 | |||
| 25bce1031b | |||
| 909622fbd7 | |||
| 2d3d6f73b5 | |||
|
|
44a27008dd | ||
|
|
33229a31ee | ||
|
|
653047146a | ||
|
|
423167fdd3 | ||
|
|
4547d5887d | ||
|
|
3790129b30 | ||
|
|
aa95750e1f | ||
|
|
ac6cd7e4c6 | ||
| b69677b709 | |||
| 0ceb9576b9 | |||
| 193ad4306e | |||
| 4290b1e795 | |||
| 3428995906 | |||
| ca3f9963c6 | |||
| ebbf7f23ac | |||
| 696c2152b3 | |||
| b66bc39db3 | |||
| df16ce6f77 | |||
| a438722eed | |||
| 4e635aa485 | |||
| 25fe886e72 | |||
| 5a2975ba65 | |||
| 094cf14d4a | |||
| 5c8eab9dfb | |||
| ae5828fdb1 | |||
| b79471e0ca | |||
| 18391ac7db | |||
| c3a1f153c1 | |||
| d940aa5a44 | |||
| d6b1f813a8 | |||
| f867a9d4ce | |||
| e2f048b2ac | |||
|
|
a834cef1f4 | ||
| a493a2842a | |||
| f3c679e615 | |||
| e69f39f6e3 | |||
| b95f30b7d6 | |||
| 17b1d524de | |||
| 66be14016b | |||
| 4be46d8299 | |||
|
|
2fb0572e08 | ||
| 169fd56527 | |||
| 97a6cbda3e | |||
| 51e04f7c6e | |||
| ee138a2b36 | |||
| 5405792fad | |||
| 1da9c21f13 | |||
| 7eed4fa97b | |||
| 49ff78cf0e | |||
| c1b6e1be87 | |||
| c84dd527b7 | |||
| b0aaf64cec | |||
| 557f16b8d5 | |||
| ed72847374 | |||
| 645bd3d383 | |||
| 2e7a7f26f8 | |||
| 3474b827b0 | |||
| 25514e9848 | |||
| d00c08dcd7 | |||
| d64e6bb17d | |||
| 855215e840 | |||
| 674a77baca | |||
| c9f025a44d | |||
| a61c44ba42 | |||
| c869d3adc4 | |||
| 387dc98e11 | |||
| 319d40146d | |||
| 2e3f5d0de9 | |||
| dc36de667d | |||
| 0904500398 | |||
| 74e8cf79bd | |||
| b7498b564a | |||
| 6d40e87032 | |||
| 1f088ff3e5 | |||
| 50d038af5d | |||
| ffa4d6580d | |||
| bf2f3762af | |||
| 35e4b3c859 | |||
| 4910413482 | |||
|
|
7ccca9ef3c | ||
|
|
6e7f015d4b | ||
| 80860232d7 | |||
| d28f983c46 | |||
| 0de1ca161c | |||
|
|
9445690cb1 | ||
| b3f37db33f | |||
| 5f7d636738 | |||
| 90a915b8b5 | |||
| 248deaecbb | |||
| a79b25d7b1 | |||
| d9a7dc0233 | |||
| f34a05c35d | |||
| 8e4b7e3847 | |||
| eb094ba0ef | |||
| 87d7e10841 | |||
| 7d35a4e1b9 | |||
| fc1268dd5b | |||
| abb52331a5 | |||
| fa44a952ed | |||
| a3cac88c91 | |||
| 04614ac6f8 | |||
| bd49b1d4bd | |||
| 40894663c2 | |||
| 7d6fe011db | |||
| 451cb2573a | |||
| 238ebc23e2 | |||
| 910822ecf2 | |||
| 9fba12519f | |||
| 3a28680162 | |||
| fa12967873 | |||
| 9f0640ca2d | |||
| c385ad8f1d | |||
| 8faafc00b0 | |||
| 8498d7d128 | |||
| 455f32faa7 | |||
| 27d0a81bcb | |||
| 52a37d170f | |||
| 236155791d | |||
| 8ef593fe98 | |||
| e65bd26ad5 | |||
| 071769679d | |||
| 6ab5b84979 | |||
| 981b708230 | |||
| 651c1b6545 | |||
| e402bfaa81 | |||
| 241bb3812c | |||
| 55addfc739 | |||
| 84b94368a9 | |||
| 8f667a0463 | |||
| d962be9d7e | |||
|
|
691e274ca7 | ||
|
|
b1eaa772a1 | ||
|
|
79bb3f6cc4 | ||
| b6deae9b23 | |||
| edde533e1b | |||
| ceb7791541 | |||
| 68c617950c | |||
| 62ad7996f1 | |||
| 270bc24b62 | |||
| 9b004bc61f | |||
|
|
f4abb284eb | ||
| f9cf6bdc85 | |||
| ebc4ca8698 | |||
| d4d720524e | |||
| 6be7c46038 | |||
|
|
eb696c8993 | ||
| 7901784a71 | |||
| 4e55edc049 | |||
| acdaa60de3 | |||
| a70a7a7ed5 | |||
| 2fb1ad035f | |||
| 28a2b82795 | |||
| bf51d5d9c4 | |||
| 5d1d8b6d4d | |||
| 129fb973f2 | |||
|
|
f094bacd67 | ||
|
|
be97e84d83 | ||
| da3086bbef | |||
| 8badb609e4 | |||
| a1a895e462 | |||
| 9ed185f3d1 | |||
| 7fdfb5cf12 | |||
| b4d4c93047 | |||
| 66299cb081 | |||
| 79450bcda6 | |||
| 3a72b0cc63 | |||
| f200d5cb03 | |||
| 3ad1db8d74 | |||
| bccefb949f | |||
| c6136b5cdb | |||
| d2d5a464a3 | |||
| 6ab814a649 | |||
| df0aceb26d | |||
| ddf056cf1d | |||
|
|
c9818e607f | ||
|
|
305f45fb30 | ||
|
|
ddb9777638 | ||
|
|
374996d8b2 | ||
|
|
6192aa6910 | ||
|
|
8e47ec325d | ||
| ed9d403281 | |||
| f38cfcc937 | |||
| 649d7122a2 | |||
| ad2561125e | |||
| 403044fc6c | |||
| e7081491ca | |||
| 594abdee55 | |||
| c9063f9d9b | |||
| e276febf0a | |||
| 592f2449d2 | |||
|
|
d08f29d7d6 | ||
|
|
4342aa6bce | ||
| 207bfb44f2 | |||
| 726adaf2bb | |||
| d16db7b56c | |||
| c4ea50f06d | |||
| 5004626d7a | |||
| 48d32943b2 | |||
| 49d8235661 | |||
| 21e2600c40 | |||
| bdd6066fc3 | |||
| 04d7c9dfb4 | |||
| cc21de3fee | |||
| cf3accb181 | |||
| a4f75d7b32 | |||
| 9cdd0fc829 | |||
| f29ed21090 | |||
| cd5db63286 | |||
| 5074002327 | |||
| 9067dedcc2 | |||
| 179a4a2e56 | |||
| 8243b6922d | |||
| ec27458393 | |||
| 2007e881e5 | |||
| d82591ae70 | |||
| 9d5e8dd785 | |||
| 07e85e095d | |||
| 9bb1a00325 | |||
| f0dc76983a | |||
| 71c4505617 | |||
| acfb0a1e3b | |||
| ff66d9db67 | |||
| 6edd2b97b9 | |||
| cdfd4ca2f4 | |||
| 308c9da384 | |||
| ca00ea7a76 | |||
| e2b7f504b0 | |||
| 20547238fc | |||
| 9caddc166b | |||
| c546b283fd | |||
| c8197b8181 | |||
| 35739289cd | |||
| 68d8c6e556 | |||
| f85d03085b | |||
| 6917203530 | |||
| 144f54eb8c | |||
| 46af643ca8 | |||
| ee1852f3a4 | |||
| a141d50902 | |||
| ab5d4b59fd | |||
| 3dbc8408f1 | |||
| 08a9a01bfb | |||
|
|
3e4d77452a | ||
| 2698076fb6 | |||
| 2f09389ddd | |||
| 8da3257856 | |||
| a4546e1045 | |||
| 3bce2f5d46 | |||
|
|
074c5aa16c | ||
| 879b70617b | |||
| cad0ab17dc | |||
| 4250f78ddf | |||
| cc4bf8ea16 | |||
| 05b40a220d | |||
| 64f5c662fa | |||
| e9146ebc77 | |||
| d5990cc0f2 | |||
|
|
b6bd497e52 | ||
|
|
2246e21340 | ||
|
|
c60f3970d1 | ||
| 0b94d866f0 | |||
| fa6643c5a2 | |||
| d0eaf4d899 | |||
| c59496f30f | |||
| 71d4b5f49f | |||
| 31efa7c980 | |||
| 89e5e1d308 | |||
| 1e3e02d1f0 | |||
| 8226e92973 | |||
| af26f73f99 | |||
|
|
1f4a266c22 | ||
|
|
93fbdcd443 | ||
|
|
0e6e90baf0 | ||
|
|
2c8179f057 | ||
| 95946606ef | |||
| 3c5f9d0bc3 | |||
| 2155347e4f | |||
| db86850d15 | |||
| 97ae1e5034 | |||
| fee755bdb7 | |||
| 4fe24790fd | |||
| fe3642edd4 | |||
| 68ecd82755 | |||
| 2c1b9c2d37 | |||
| cddc1b362e | |||
| 89bdbedc0f | |||
| 3a4e82f025 | |||
| c8aca62d03 | |||
| 8b9bcbc777 | |||
| 00d6a49653 | |||
| ea9c4a1957 | |||
| 7680ecbdc4 | |||
| 00a5d19534 | |||
| 2d1ac7b266 | |||
| 2852383e4e | |||
| 393b593785 | |||
| 32df925fa6 | |||
| 9b2bbe03ee | |||
| 7e872088d0 | |||
|
|
77a6db1cab | ||
|
|
bb56a11bda | ||
| 7ea2be387e | |||
| 81cb62fda7 | |||
| 8b42896cc6 | |||
|
|
5df3f404f8 | ||
|
|
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 | |||
|
|
eec87bd814 | ||
| 649a63db6f | |||
| 6aa8ed1280 | |||
| 9224afb78d | |||
| 5e879b85a8 | |||
| 2c03b434e1 | |||
| 55a6f44651 | |||
| 971a2652e3 | |||
| 68aa8800b6 | |||
| dd4d12f287 | |||
| 7063609f05 | |||
| b32c8d5fa4 | |||
| f8163241ef | |||
|
|
843e2a8a0e | ||
| 419d6a8e18 | |||
|
|
6a0d421ed0 | ||
|
|
c1c3a92331 | ||
|
|
1dfc8187ca | ||
|
|
075c4d4822 | ||
|
|
03f9df4ff0 | ||
| 07fa3eb922 | |||
| f4a6cf2002 | |||
| f93da93cf0 | |||
| b068f9a262 | |||
|
|
489ff65e34 | ||
|
|
bf76c57de7 | ||
|
|
5fa059b4a8 | ||
|
|
2f92b27446 | ||
|
|
2bc87662aa | ||
|
|
73228a1514 | ||
| 5d345f65a3 | |||
| ccc8c04782 | |||
| 58ccfed41d | |||
| 59b05d4214 | |||
|
|
f46a902256 | ||
| 39b810bd79 | |||
| 22417715e7 | |||
| d21777fbc1 | |||
| b22a6bc163 | |||
| 1c3527e1a4 | |||
| 4d7ad6ef7f | |||
| 3ea8b477d8 | |||
| ea4dd12bff | |||
|
|
a13552dd8d | ||
|
|
89c14c2e9a | ||
|
|
22b9876b68 | ||
|
|
0848e34243 | ||
| 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 | |||
| b0c3c11bd9 | |||
|
|
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 | ||
|
|
5c56de7218 | ||
|
|
f33e5c2845 | ||
|
|
52b362dedf | ||
|
|
ecb28eb480 | ||
|
|
69a5f94642 | ||
| a984745689 | |||
| 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 | ||
| 6076bb3b2b | |||
|
|
1a012dfca1 | ||
|
|
e0fe2439e6 | ||
|
|
34d3009439 | ||
|
|
70c2838421 | ||
|
|
63a5b4803c | ||
|
|
67760c8bea | ||
|
|
9130d556d8 | ||
|
|
50d46006ae | ||
|
|
583a050281 | ||
|
|
2185a65de6 | ||
| 4ea99b8a10 | |||
| 3d07e1a10b | |||
|
|
9134d2856f | ||
| 86525e7239 | |||
| 195171f9ed | |||
|
|
33c4be5b2f | ||
|
|
fea2c3c6b2 | ||
|
|
281686ba58 | ||
|
|
0b91fcb636 | ||
|
|
807f1381fb | ||
|
|
ac56a63809 | ||
|
|
e4798b9ed8 | ||
|
|
7584346c82 | ||
|
|
68adfa80af | ||
| 29330aa5d3 | |||
| 65ff2c0afe | |||
| de4d47de95 | |||
| ae41a3f316 | |||
|
|
1e8c299be2 | ||
|
|
39cb60e72b | ||
| 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 | |||
|
|
d5d4dbb078 | ||
|
|
815f275d8b | ||
|
|
fdad8f0c34 | ||
| 4588f1ec75 | |||
| 629f7f05c7 | |||
| 0f18686243 | |||
| 2a2587b13d | |||
| 489fdd5e4b | |||
| fe680eb192 | |||
| 613440ff63 | |||
| 64121b1e92 | |||
| f16927f316 | |||
| cb50c1bd8b | |||
| 921ad86274 | |||
| ac76107752 | |||
| 2359b1edd2 | |||
| 2750681d78 | |||
| eaac4d3de0 | |||
|
|
827b7b64d2 | ||
| f243968dfa | |||
| 8d9e2bdc71 | |||
| 6dbbb6b61b | |||
| f89bf32390 | |||
| ef195aa4ef | |||
|
|
843230a1cb | ||
| 84e63f3b38 | |||
| b90816fdf8 | |||
| 40c4a42921 | |||
| 26f89391d3 | |||
| aaae72cf84 | |||
| 3e55cff153 | |||
| bd778a2204 | |||
| 235c196f14 | |||
| e475c161cb | |||
|
|
e5cd33cedb | ||
|
|
a074654916 | ||
| 54f9d1eb63 | |||
| 08e96109a7 | |||
| 81ad33d9e3 | |||
| aecc95825b | |||
| 37c6ac3a88 | |||
| 772d0beac3 | |||
| 64fdfd81ee | |||
| 1b09b9faa4 | |||
| 6f0ebb2d94 | |||
| 12099753ad | |||
| db4e09efa3 | |||
| 8fa1e6ee11 | |||
| e7a33dfd64 | |||
| 55c411a495 | |||
| 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 | |||
| a3c6cc1daa | |||
| 1773fc0e0d | |||
| 6d6f7fb89b | |||
| 449ce3176e | |||
| 5383f9f097 | |||
| a16d17c422 | |||
| 31cc0764a9 | |||
| 8f8adfa39e | |||
| 5044f3e58f | |||
|
|
a83c88e886 | ||
|
|
bcfc7630d1 | ||
|
|
3b7daafad7 |
6
.idea/ant.xml
generated
Normal file
6
.idea/ant.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AntConfiguration">
|
||||||
|
<buildFile url="file://$PROJECT_DIR$/build.xml" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
22
.idea/compiler.xml
generated
Normal file
22
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<resourceExtensions />
|
||||||
|
<wildcardResourcePatterns>
|
||||||
|
<entry name="!?*.java" />
|
||||||
|
<entry name="!?*.form" />
|
||||||
|
<entry name="!?*.class" />
|
||||||
|
<entry name="!?*.groovy" />
|
||||||
|
<entry name="!?*.scala" />
|
||||||
|
<entry name="!?*.flex" />
|
||||||
|
<entry name="!?*.kt" />
|
||||||
|
<entry name="!?*.clj" />
|
||||||
|
<entry name="!?*.aj" />
|
||||||
|
</wildcardResourcePatterns>
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile default="true" name="Default" enabled="false">
|
||||||
|
<processorPath useClasspath="true" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
3
.idea/copyright/profiles_settings.xml
generated
Normal file
3
.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<component name="CopyrightManager">
|
||||||
|
<settings default="" />
|
||||||
|
</component>
|
||||||
9
.idea/libraries/javax_servlet_jsp_2_2_0_v201112011158.xml
generated
Normal file
9
.idea/libraries/javax_servlet_jsp_2_2_0_v201112011158.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="javax.servlet.jsp-2.2.0.v201112011158">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
22
.idea/libraries/jettylib.xml
generated
Normal file
22
.idea/libraries/jettylib.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="jettylib">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-security-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlets-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-deploy-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-util-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlet-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-http-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-xml-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-server-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/servlet-api-3.0.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-jmx-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-webapp-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-io-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-continuation-8.1.17.v20150415.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-rewrite-8.1.17.v20150415.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/jrobin_1_5_9_1.xml
generated
Normal file
9
.idea/libraries/jrobin_1_5_9_1.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="jrobin-1.5.9.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jrobin/jrobin-1.5.9.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
10
.idea/libraries/lib.xml
generated
Normal file
10
.idea/libraries/lib.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="lib">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/jstl.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/standard.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/start.xml
generated
Normal file
9
.idea/libraries/start.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="start">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/start.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/systray4j.xml
generated
Normal file
9
.idea/libraries/systray4j.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="systray4j">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/systray/java/lib/systray4j.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/tomcat_coyote_util.xml
generated
Normal file
9
.idea/libraries/tomcat_coyote_util.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="tomcat-coyote-util">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat/lib/tomcat-coyote-util.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
12
.idea/libraries/tomcat_lib.xml
generated
Normal file
12
.idea/libraries/tomcat_lib.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="tomcat-lib">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/el-api.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper.jar!/" />
|
||||||
|
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/wrapper.xml
generated
Normal file
9
.idea/libraries/wrapper.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="wrapper">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/all/wrapper.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
9
.idea/libraries/wrapper_win.xml
generated
Normal file
9
.idea/libraries/wrapper_win.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="wrapper-win">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/win-all/wrapper.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
57
.idea/misc.xml
generated
Normal file
57
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ClientPropertiesManager">
|
||||||
|
<properties class="javax.swing.AbstractButton">
|
||||||
|
<property name="hideActionText" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JComponent">
|
||||||
|
<property name="html.disable" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JEditorPane">
|
||||||
|
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
|
||||||
|
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
|
||||||
|
<property name="charset" class="java.lang.String" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JList">
|
||||||
|
<property name="List.isFileList" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JPasswordField">
|
||||||
|
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JSlider">
|
||||||
|
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
|
||||||
|
<property name="JSlider.isFilled" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JTable">
|
||||||
|
<property name="Table.isFileList" class="java.lang.Boolean" />
|
||||||
|
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
|
||||||
|
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JToolBar">
|
||||||
|
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.JTree">
|
||||||
|
<property name="JTree.lineStyle" class="java.lang.String" />
|
||||||
|
</properties>
|
||||||
|
<properties class="javax.swing.text.JTextComponent">
|
||||||
|
<property name="caretAspectRatio" class="java.lang.Double" />
|
||||||
|
<property name="caretWidth" class="java.lang.Integer" />
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<entry_points version="2.0" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||||
|
<OptionsSetting value="true" id="Add" />
|
||||||
|
<OptionsSetting value="true" id="Remove" />
|
||||||
|
<OptionsSetting value="true" id="Checkout" />
|
||||||
|
<OptionsSetting value="true" id="Update" />
|
||||||
|
<OptionsSetting value="true" id="Status" />
|
||||||
|
<OptionsSetting value="true" id="Edit" />
|
||||||
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
27
.idea/modules.xml
generated
Normal file
27
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/BOB/BOB.iml" filepath="$PROJECT_DIR$/apps/BOB/BOB.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/addressbook/addressbook.iml" filepath="$PROJECT_DIR$/apps/addressbook/addressbook.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/admin/admin.iml" filepath="$PROJECT_DIR$/apps/admin/admin.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/core/core.iml" filepath="$PROJECT_DIR$/core/core.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" filepath="$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" filepath="$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" filepath="$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" filepath="$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" filepath="$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/installer/installer.iml" filepath="$PROJECT_DIR$/installer/installer.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/jetty/jetty.iml" filepath="$PROJECT_DIR$/apps/jetty/jetty.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" filepath="$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/router/router.iml" filepath="$PROJECT_DIR$/router/router.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" filepath="$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/sam/sam.iml" filepath="$PROJECT_DIR$/apps/sam/sam.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/streaming/streaming.iml" filepath="$PROJECT_DIR$/apps/streaming/streaming.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/susidns/susidns.iml" filepath="$PROJECT_DIR$/apps/susidns/susidns.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/susimail/susimail.iml" filepath="$PROJECT_DIR$/apps/susimail/susimail.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/systray/systray.iml" filepath="$PROJECT_DIR$/apps/systray/systray.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" filepath="$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/runConfigurations/updater.xml
generated
Normal file
6
.idea/runConfigurations/updater.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="updater" type="AntRunConfiguration" factoryName="Ant Target">
|
||||||
|
<antsettings antfile="file://$PROJECT_DIR$/build.xml" target="updater" />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
11
.mtn-ignore
11
.mtn-ignore
@@ -28,18 +28,23 @@ web-fragment.xml
|
|||||||
web-out.xml
|
web-out.xml
|
||||||
|
|
||||||
# Temporary/build dirs
|
# Temporary/build dirs
|
||||||
^build
|
^build$
|
||||||
^pkg-temp
|
^pkg-temp
|
||||||
/build
|
/build$
|
||||||
/classes
|
/classes
|
||||||
/dist
|
/dist
|
||||||
^installer/resources/locale/mo
|
^installer/resources/locale/mo
|
||||||
/tmp
|
/tmp
|
||||||
^apps/jetty/jettylib
|
^apps/jetty/jettylib
|
||||||
|
|
||||||
|
# MSVC files
|
||||||
|
core/c/jcpuid/msvc/*.opendb
|
||||||
|
core/c/jcpuid/msvc/*.pdb
|
||||||
|
core/c/jcpuid/msvc/*.sdf
|
||||||
|
core/c/jcpuid/msvc/*.user
|
||||||
|
|
||||||
# Debian-related
|
# Debian-related
|
||||||
^debian/copyright
|
^debian/copyright
|
||||||
^debian/changelog
|
|
||||||
^.pc/
|
^.pc/
|
||||||
|
|
||||||
# Build property overrides
|
# Build property overrides
|
||||||
|
|||||||
133
.tx/config
133
.tx/config
@@ -6,10 +6,12 @@ trans.cs = apps/i2ptunnel/locale/messages_cs.po
|
|||||||
trans.da = apps/i2ptunnel/locale/messages_da.po
|
trans.da = apps/i2ptunnel/locale/messages_da.po
|
||||||
trans.de = apps/i2ptunnel/locale/messages_de.po
|
trans.de = apps/i2ptunnel/locale/messages_de.po
|
||||||
trans.es = apps/i2ptunnel/locale/messages_es.po
|
trans.es = apps/i2ptunnel/locale/messages_es.po
|
||||||
|
trans.fi = apps/i2ptunnel/locale/messages_fi.po
|
||||||
trans.fr = apps/i2ptunnel/locale/messages_fr.po
|
trans.fr = apps/i2ptunnel/locale/messages_fr.po
|
||||||
trans.hu = apps/i2ptunnel/locale/messages_hu.po
|
trans.hu = apps/i2ptunnel/locale/messages_hu.po
|
||||||
trans.it = apps/i2ptunnel/locale/messages_it.po
|
trans.it = apps/i2ptunnel/locale/messages_it.po
|
||||||
trans.ja = apps/i2ptunnel/locale/messages_ja.po
|
trans.ja = apps/i2ptunnel/locale/messages_ja.po
|
||||||
|
trans.ko = apps/i2ptunnel/locale/messages_ko.po
|
||||||
trans.nb = apps/i2ptunnel/locale/messages_nb.po
|
trans.nb = apps/i2ptunnel/locale/messages_nb.po
|
||||||
trans.nl = apps/i2ptunnel/locale/messages_nl.po
|
trans.nl = apps/i2ptunnel/locale/messages_nl.po
|
||||||
trans.nn = apps/i2ptunnel/locale/messages_nn.po
|
trans.nn = apps/i2ptunnel/locale/messages_nn.po
|
||||||
@@ -20,9 +22,11 @@ trans.ro = apps/i2ptunnel/locale/messages_ro.po
|
|||||||
trans.ru_RU = apps/i2ptunnel/locale/messages_ru.po
|
trans.ru_RU = apps/i2ptunnel/locale/messages_ru.po
|
||||||
trans.sk = apps/i2ptunnel/locale/messages_sk.po
|
trans.sk = apps/i2ptunnel/locale/messages_sk.po
|
||||||
trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po
|
trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po
|
||||||
|
trans.tr_TR = apps/i2ptunnel/locale/messages_tr.po
|
||||||
trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po
|
trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po
|
||||||
trans.vi = apps/i2ptunnel/locale/messages_vi.po
|
trans.vi = apps/i2ptunnel/locale/messages_vi.po
|
||||||
trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
|
trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
|
||||||
|
trans.zh_TW = apps/i2ptunnel/locale/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.proxy]
|
[I2P.proxy]
|
||||||
source_file = apps/i2ptunnel/locale-proxy/messages_en.po
|
source_file = apps/i2ptunnel/locale-proxy/messages_en.po
|
||||||
@@ -31,9 +35,13 @@ trans.ar = apps/i2ptunnel/locale-proxy/messages_ar.po
|
|||||||
trans.cs = apps/i2ptunnel/locale-proxy/messages_cs.po
|
trans.cs = apps/i2ptunnel/locale-proxy/messages_cs.po
|
||||||
trans.de = apps/i2ptunnel/locale-proxy/messages_de.po
|
trans.de = apps/i2ptunnel/locale-proxy/messages_de.po
|
||||||
trans.es = apps/i2ptunnel/locale-proxy/messages_es.po
|
trans.es = apps/i2ptunnel/locale-proxy/messages_es.po
|
||||||
|
trans.fi = apps/i2ptunnel/locale-proxy/messages_fi.po
|
||||||
trans.fr = apps/i2ptunnel/locale-proxy/messages_fr.po
|
trans.fr = apps/i2ptunnel/locale-proxy/messages_fr.po
|
||||||
trans.hu = apps/i2ptunnel/locale-proxy/messages_hu.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.it = apps/i2ptunnel/locale-proxy/messages_it.po
|
||||||
|
trans.ko = apps/i2ptunnel/locale-proxy/messages_ko.po
|
||||||
trans.nb = apps/i2ptunnel/locale-proxy/messages_nb.po
|
trans.nb = apps/i2ptunnel/locale-proxy/messages_nb.po
|
||||||
trans.nl = apps/i2ptunnel/locale-proxy/messages_nl.po
|
trans.nl = apps/i2ptunnel/locale-proxy/messages_nl.po
|
||||||
trans.pl = apps/i2ptunnel/locale-proxy/messages_pl.po
|
trans.pl = apps/i2ptunnel/locale-proxy/messages_pl.po
|
||||||
@@ -43,6 +51,7 @@ trans.ro = apps/i2ptunnel/locale-proxy/messages_ro.po
|
|||||||
trans.ru_RU = apps/i2ptunnel/locale-proxy/messages_ru.po
|
trans.ru_RU = apps/i2ptunnel/locale-proxy/messages_ru.po
|
||||||
trans.sk = apps/i2ptunnel/locale-proxy/messages_sk.po
|
trans.sk = apps/i2ptunnel/locale-proxy/messages_sk.po
|
||||||
trans.sv_SE = apps/i2ptunnel/locale-proxy/messages_sv.po
|
trans.sv_SE = apps/i2ptunnel/locale-proxy/messages_sv.po
|
||||||
|
trans.tr_TR = apps/i2ptunnel/locale-proxy/messages_tr.po
|
||||||
trans.uk_UA = apps/i2ptunnel/locale-proxy/messages_uk.po
|
trans.uk_UA = apps/i2ptunnel/locale-proxy/messages_uk.po
|
||||||
trans.vi = apps/i2ptunnel/locale-proxy/messages_vi.po
|
trans.vi = apps/i2ptunnel/locale-proxy/messages_vi.po
|
||||||
trans.zh_CN = apps/i2ptunnel/locale-proxy/messages_zh.po
|
trans.zh_CN = apps/i2ptunnel/locale-proxy/messages_zh.po
|
||||||
@@ -62,6 +71,7 @@ trans.fr = apps/routerconsole/locale/messages_fr.po
|
|||||||
trans.hu = apps/routerconsole/locale/messages_hu.po
|
trans.hu = apps/routerconsole/locale/messages_hu.po
|
||||||
trans.it = apps/routerconsole/locale/messages_it.po
|
trans.it = apps/routerconsole/locale/messages_it.po
|
||||||
trans.ja = apps/routerconsole/locale/messages_ja.po
|
trans.ja = apps/routerconsole/locale/messages_ja.po
|
||||||
|
trans.ko = apps/routerconsole/locale/messages_ko.po
|
||||||
trans.nb = apps/routerconsole/locale/messages_nb.po
|
trans.nb = apps/routerconsole/locale/messages_nb.po
|
||||||
trans.nl = apps/routerconsole/locale/messages_nl.po
|
trans.nl = apps/routerconsole/locale/messages_nl.po
|
||||||
trans.pl = apps/routerconsole/locale/messages_pl.po
|
trans.pl = apps/routerconsole/locale/messages_pl.po
|
||||||
@@ -74,18 +84,26 @@ trans.tr_TR = apps/routerconsole/locale/messages_tr.po
|
|||||||
trans.uk_UA = apps/routerconsole/locale/messages_uk.po
|
trans.uk_UA = apps/routerconsole/locale/messages_uk.po
|
||||||
trans.vi = apps/routerconsole/locale/messages_vi.po
|
trans.vi = apps/routerconsole/locale/messages_vi.po
|
||||||
trans.zh_CN = apps/routerconsole/locale/messages_zh.po
|
trans.zh_CN = apps/routerconsole/locale/messages_zh.po
|
||||||
|
trans.zh_TW = apps/routerconsole/locale/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.welcome]
|
[I2P.welcome]
|
||||||
source_file = apps/routerconsole/locale-news/messages_en.po
|
source_file = apps/routerconsole/locale-news/messages_en.po
|
||||||
source_lang = en
|
source_lang = en
|
||||||
trans.ar = apps/routerconsole/locale-news/messages_ar.po
|
trans.ar = apps/routerconsole/locale-news/messages_ar.po
|
||||||
|
trans.cs = apps/routerconsole/locale-news/messages_cs.po
|
||||||
trans.de = apps/routerconsole/locale-news/messages_de.po
|
trans.de = apps/routerconsole/locale-news/messages_de.po
|
||||||
|
trans.el = apps/routerconsole/locale-news/messages_el.po
|
||||||
trans.es = apps/routerconsole/locale-news/messages_es.po
|
trans.es = 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.fr = apps/routerconsole/locale-news/messages_fr.po
|
||||||
|
trans.gl = apps/routerconsole/locale-news/messages_gl.po
|
||||||
trans.he = apps/routerconsole/locale-news/messages_he.po
|
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.it = apps/routerconsole/locale-news/messages_it.po
|
||||||
trans.ja = apps/routerconsole/locale-news/messages_ja.po
|
trans.ja = apps/routerconsole/locale-news/messages_ja.po
|
||||||
trans.ko = apps/routerconsole/locale-news/messages_ko.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.nb = apps/routerconsole/locale-news/messages_nb.po
|
||||||
trans.nl = apps/routerconsole/locale-news/messages_nl.po
|
trans.nl = apps/routerconsole/locale-news/messages_nl.po
|
||||||
trans.pl = apps/routerconsole/locale-news/messages_pl.po
|
trans.pl = apps/routerconsole/locale-news/messages_pl.po
|
||||||
@@ -94,10 +112,13 @@ trans.pt_BR = apps/routerconsole/locale-news/messages_pt_BR.po
|
|||||||
trans.ro = apps/routerconsole/locale-news/messages_ro.po
|
trans.ro = apps/routerconsole/locale-news/messages_ro.po
|
||||||
trans.ru_RU = apps/routerconsole/locale-news/messages_ru.po
|
trans.ru_RU = apps/routerconsole/locale-news/messages_ru.po
|
||||||
trans.sk = apps/routerconsole/locale-news/messages_sk.po
|
trans.sk = apps/routerconsole/locale-news/messages_sk.po
|
||||||
|
trans.sq = apps/routerconsole/locale-news/messages_sq.po
|
||||||
|
trans.sr = apps/routerconsole/locale-news/messages_sr.po
|
||||||
trans.sv_SE = apps/routerconsole/locale-news/messages_sv.po
|
trans.sv_SE = apps/routerconsole/locale-news/messages_sv.po
|
||||||
trans.tr_TR = apps/routerconsole/locale-news/messages_tr.po
|
trans.tr_TR = apps/routerconsole/locale-news/messages_tr.po
|
||||||
trans.uk_UA = apps/routerconsole/locale-news/messages_uk.po
|
trans.uk_UA = apps/routerconsole/locale-news/messages_uk.po
|
||||||
trans.zh_CN = apps/routerconsole/locale-news/messages_zh.po
|
trans.zh_CN = apps/routerconsole/locale-news/messages_zh.po
|
||||||
|
trans.zh_TW = apps/routerconsole/locale-news/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.countries]
|
[I2P.countries]
|
||||||
type = PO
|
type = PO
|
||||||
@@ -109,11 +130,15 @@ trans.de = apps/routerconsole/locale-countries/messages_de.po
|
|||||||
trans.el = apps/routerconsole/locale-countries/messages_el.po
|
trans.el = apps/routerconsole/locale-countries/messages_el.po
|
||||||
trans.es = apps/routerconsole/locale-countries/messages_es.po
|
trans.es = apps/routerconsole/locale-countries/messages_es.po
|
||||||
trans.et_EE = apps/routerconsole/locale-countries/messages_et.po
|
trans.et_EE = apps/routerconsole/locale-countries/messages_et.po
|
||||||
|
trans.fa = apps/routerconsole/locale-countries/messages_fa.po
|
||||||
trans.fi = apps/routerconsole/locale-countries/messages_fi.po
|
trans.fi = apps/routerconsole/locale-countries/messages_fi.po
|
||||||
trans.fr = apps/routerconsole/locale-countries/messages_fr.po
|
trans.fr = apps/routerconsole/locale-countries/messages_fr.po
|
||||||
|
trans.gl = apps/routerconsole/locale-countries/messages_gl.po
|
||||||
trans.hu = apps/routerconsole/locale-countries/messages_hu.po
|
trans.hu = apps/routerconsole/locale-countries/messages_hu.po
|
||||||
trans.it = apps/routerconsole/locale-countries/messages_it.po
|
trans.it = apps/routerconsole/locale-countries/messages_it.po
|
||||||
trans.ja = apps/routerconsole/locale-countries/messages_ja.po
|
trans.ja = apps/routerconsole/locale-countries/messages_ja.po
|
||||||
|
trans.ko = apps/routerconsole/locale-countries/messages_ko.po
|
||||||
|
trans.mg = apps/routerconsole/locale-countries/messages_mg.po
|
||||||
trans.nb = apps/routerconsole/locale-countries/messages_nb.po
|
trans.nb = apps/routerconsole/locale-countries/messages_nb.po
|
||||||
trans.nl = apps/routerconsole/locale-countries/messages_nl.po
|
trans.nl = apps/routerconsole/locale-countries/messages_nl.po
|
||||||
trans.pl = apps/routerconsole/locale-countries/messages_pl.po
|
trans.pl = apps/routerconsole/locale-countries/messages_pl.po
|
||||||
@@ -124,10 +149,11 @@ trans.ru_RU = apps/routerconsole/locale-countries/messages_ru.po
|
|||||||
trans.sk = apps/routerconsole/locale-countries/messages_sk.po
|
trans.sk = apps/routerconsole/locale-countries/messages_sk.po
|
||||||
trans.sq = apps/routerconsole/locale-countries/messages_sq.po
|
trans.sq = apps/routerconsole/locale-countries/messages_sq.po
|
||||||
trans.sv_SE = apps/routerconsole/locale-countries/messages_sv.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.tr_TR = apps/routerconsole/locale-countries/messages_tr.po
|
||||||
|
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
|
||||||
trans.vi = apps/routerconsole/locale-countries/messages_vi.po
|
trans.vi = apps/routerconsole/locale-countries/messages_vi.po
|
||||||
trans.zh_CN = apps/routerconsole/locale-countries/messages_zh.po
|
trans.zh_CN = apps/routerconsole/locale-countries/messages_zh.po
|
||||||
|
trans.zh_TW = apps/routerconsole/locale-countries/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.i2psnark]
|
[I2P.i2psnark]
|
||||||
source_file = apps/i2psnark/locale/messages_en.po
|
source_file = apps/i2psnark/locale/messages_en.po
|
||||||
@@ -136,18 +162,23 @@ trans.ar = apps/i2psnark/locale/messages_ar.po
|
|||||||
trans.cs = apps/i2psnark/locale/messages_cs.po
|
trans.cs = apps/i2psnark/locale/messages_cs.po
|
||||||
trans.de = apps/i2psnark/locale/messages_de.po
|
trans.de = apps/i2psnark/locale/messages_de.po
|
||||||
trans.es = apps/i2psnark/locale/messages_es.po
|
trans.es = apps/i2psnark/locale/messages_es.po
|
||||||
|
trans.fi = apps/i2psnark/locale/messages_fi.po
|
||||||
trans.fr = apps/i2psnark/locale/messages_fr.po
|
trans.fr = apps/i2psnark/locale/messages_fr.po
|
||||||
trans.hu = apps/i2psnark/locale/messages_hu.po
|
trans.hu = apps/i2psnark/locale/messages_hu.po
|
||||||
trans.it = apps/i2psnark/locale/messages_it.po
|
trans.it = apps/i2psnark/locale/messages_it.po
|
||||||
|
trans.ja = apps/i2psnark/locale/messages_ja.po
|
||||||
|
trans.ko = apps/i2psnark/locale/messages_ko.po
|
||||||
trans.nb = apps/i2psnark/locale/messages_nb.po
|
trans.nb = apps/i2psnark/locale/messages_nb.po
|
||||||
trans.nl = apps/i2psnark/locale/messages_nl.po
|
trans.nl = apps/i2psnark/locale/messages_nl.po
|
||||||
trans.pl = apps/i2psnark/locale/messages_pl.po
|
trans.pl = apps/i2psnark/locale/messages_pl.po
|
||||||
trans.pt = apps/i2psnark/locale/messages_pt.po
|
trans.pt = apps/i2psnark/locale/messages_pt.po
|
||||||
trans.pt_BR = apps/i2psnark/locale/messages_pt_bR.po
|
trans.pt_BR = apps/i2psnark/locale/messages_pt_BR.po
|
||||||
trans.ro = apps/i2psnark/locale/messages_ro.po
|
trans.ro = apps/i2psnark/locale/messages_ro.po
|
||||||
trans.ru_RU = apps/i2psnark/locale/messages_ru.po
|
trans.ru_RU = apps/i2psnark/locale/messages_ru.po
|
||||||
trans.sk = apps/i2psnark/locale/messages_sk.po
|
trans.sk = apps/i2psnark/locale/messages_sk.po
|
||||||
trans.sv_SE = apps/i2psnark/locale/messages_sv.po
|
trans.sv_SE = apps/i2psnark/locale/messages_sv.po
|
||||||
|
trans.tr_TR = apps/i2psnark/locale/messages_tr.po
|
||||||
|
trans.uk_UA = apps/i2psnark/locale/messages_uk.po
|
||||||
trans.vi = apps/i2psnark/locale/messages_vi.po
|
trans.vi = apps/i2psnark/locale/messages_vi.po
|
||||||
trans.zh_CN = apps/i2psnark/locale/messages_zh.po
|
trans.zh_CN = apps/i2psnark/locale/messages_zh.po
|
||||||
|
|
||||||
@@ -160,10 +191,13 @@ trans.da = apps/susidns/locale/messages_da.po
|
|||||||
trans.de = apps/susidns/locale/messages_de.po
|
trans.de = apps/susidns/locale/messages_de.po
|
||||||
trans.el = apps/susidns/locale/messages_el.po
|
trans.el = apps/susidns/locale/messages_el.po
|
||||||
trans.es = apps/susidns/locale/messages_es.po
|
trans.es = apps/susidns/locale/messages_es.po
|
||||||
|
trans.fi = apps/susidns/locale/messages_fi.po
|
||||||
trans.fr = apps/susidns/locale/messages_fr.po
|
trans.fr = apps/susidns/locale/messages_fr.po
|
||||||
|
trans.gl = apps/susidns/locale/messages_gl.po
|
||||||
trans.hu = apps/susidns/locale/messages_hu.po
|
trans.hu = apps/susidns/locale/messages_hu.po
|
||||||
trans.it = apps/susidns/locale/messages_it.po
|
trans.it = apps/susidns/locale/messages_it.po
|
||||||
trans.ja = apps/susidns/locale/messages_ja.po
|
trans.ja = apps/susidns/locale/messages_ja.po
|
||||||
|
trans.ko = apps/susidns/locale/messages_ko.po
|
||||||
trans.nl = apps/susidns/locale/messages_nl.po
|
trans.nl = apps/susidns/locale/messages_nl.po
|
||||||
trans.pl = apps/susidns/locale/messages_pl.po
|
trans.pl = apps/susidns/locale/messages_pl.po
|
||||||
trans.pt = apps/susidns/locale/messages_pt.po
|
trans.pt = apps/susidns/locale/messages_pt.po
|
||||||
@@ -175,27 +209,40 @@ trans.tr_TR = apps/susidns/locale/messages_tr.po
|
|||||||
trans.uk_UA = apps/susidns/locale/messages_uk.po
|
trans.uk_UA = apps/susidns/locale/messages_uk.po
|
||||||
trans.vi = apps/susidns/locale/messages_vi.po
|
trans.vi = apps/susidns/locale/messages_vi.po
|
||||||
trans.zh_CN = apps/susidns/locale/messages_zh.po
|
trans.zh_CN = apps/susidns/locale/messages_zh.po
|
||||||
|
trans.zh_TW = apps/susidns/locale/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.desktopgui]
|
[I2P.desktopgui]
|
||||||
source_file = apps/desktopgui/locale/messages_en.po
|
source_file = apps/desktopgui/locale/messages_en.po
|
||||||
source_lang = en
|
source_lang = en
|
||||||
trans.ar = apps/desktopgui/locale/messages_ar.po
|
trans.ar = apps/desktopgui/locale/messages_ar.po
|
||||||
|
trans.bg = apps/desktopgui/locale/messages_bg.po
|
||||||
|
trans.ca = apps/desktopgui/locale/messages_ca.po
|
||||||
trans.cs = apps/desktopgui/locale/messages_cs.po
|
trans.cs = apps/desktopgui/locale/messages_cs.po
|
||||||
trans.da = apps/desktopgui/locale/messages_da.po
|
trans.da = apps/desktopgui/locale/messages_da.po
|
||||||
trans.de = apps/desktopgui/locale/messages_de.po
|
trans.de = apps/desktopgui/locale/messages_de.po
|
||||||
trans.el = apps/desktopgui/locale/messages_el.po
|
trans.el = apps/desktopgui/locale/messages_el.po
|
||||||
trans.es = apps/desktopgui/locale/messages_es.po
|
trans.es = apps/desktopgui/locale/messages_es.po
|
||||||
|
trans.fa = apps/desktopgui/locale/messages_fa.po
|
||||||
|
trans.fi = apps/desktopgui/locale/messages_fi.po
|
||||||
trans.fr = apps/desktopgui/locale/messages_fr.po
|
trans.fr = apps/desktopgui/locale/messages_fr.po
|
||||||
|
trans.gl = apps/desktopgui/locale/messages_gl.po
|
||||||
trans.hu = apps/desktopgui/locale/messages_hu.po
|
trans.hu = apps/desktopgui/locale/messages_hu.po
|
||||||
|
;; Java converts id to in
|
||||||
|
trans.id = apps/desktopgui/locale/messages_in.po
|
||||||
trans.it = apps/desktopgui/locale/messages_it.po
|
trans.it = apps/desktopgui/locale/messages_it.po
|
||||||
trans.ja = apps/desktopgui/locale/messages_ja.po
|
trans.ja = apps/desktopgui/locale/messages_ja.po
|
||||||
|
trans.ko = apps/desktopgui/locale/messages_ko.po
|
||||||
|
trans.mg = apps/desktopgui/locale/messages_mg.po
|
||||||
|
trans.nb = apps/desktopgui/locale/messages_nb.po
|
||||||
trans.nl = apps/desktopgui/locale/messages_nl.po
|
trans.nl = apps/desktopgui/locale/messages_nl.po
|
||||||
trans.pl = apps/desktopgui/locale/messages_pl.po
|
trans.pl = apps/desktopgui/locale/messages_pl.po
|
||||||
|
trans.pt = apps/desktopgui/locale/messages_pt.po
|
||||||
trans.pt_BR = apps/desktopgui/locale/messages_pt_BR.po
|
trans.pt_BR = apps/desktopgui/locale/messages_pt_BR.po
|
||||||
trans.ro = apps/desktopgui/locale/messages_ro.po
|
trans.ro = apps/desktopgui/locale/messages_ro.po
|
||||||
trans.ru_RU = apps/desktopgui/locale/messages_ru.po
|
trans.ru_RU = apps/desktopgui/locale/messages_ru.po
|
||||||
trans.sk = apps/desktopgui/locale/messages_sk.po
|
trans.sk = apps/desktopgui/locale/messages_sk.po
|
||||||
trans.sv_SE = apps/desktopgui/locale/messages_sv.po
|
trans.sv_SE = apps/desktopgui/locale/messages_sv.po
|
||||||
|
trans.sq = apps/desktopgui/locale/messages_sq.po
|
||||||
trans.uk_UA = apps/desktopgui/locale/messages_uk.po
|
trans.uk_UA = apps/desktopgui/locale/messages_uk.po
|
||||||
trans.tr_TR = apps/desktopgui/locale/messages_tr.po
|
trans.tr_TR = apps/desktopgui/locale/messages_tr.po
|
||||||
trans.vi = apps/desktopgui/locale/messages_vi.po
|
trans.vi = apps/desktopgui/locale/messages_vi.po
|
||||||
@@ -204,24 +251,37 @@ trans.zh_CN = apps/desktopgui/locale/messages_zh.po
|
|||||||
[I2P.susimail]
|
[I2P.susimail]
|
||||||
source_file = apps/susimail/locale/messages_en.po
|
source_file = apps/susimail/locale/messages_en.po
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
trans.ar = apps/susimail/locale/messages_ar.po
|
||||||
trans.cs = apps/susimail/locale/messages_cs.po
|
trans.cs = apps/susimail/locale/messages_cs.po
|
||||||
trans.da = apps/susimail/locale/messages_da.po
|
trans.da = apps/susimail/locale/messages_da.po
|
||||||
trans.de = apps/susimail/locale/messages_de.po
|
trans.de = apps/susimail/locale/messages_de.po
|
||||||
|
trans.el = apps/susimail/locale/messages_el.po
|
||||||
trans.es = apps/susimail/locale/messages_es.po
|
trans.es = apps/susimail/locale/messages_es.po
|
||||||
|
trans.fi = apps/susimail/locale/messages_fi.po
|
||||||
trans.fr = apps/susimail/locale/messages_fr.po
|
trans.fr = apps/susimail/locale/messages_fr.po
|
||||||
|
trans.gl = apps/susimail/locale/messages_gl.po
|
||||||
trans.hu = apps/susimail/locale/messages_hu.po
|
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.it = apps/susimail/locale/messages_it.po
|
||||||
trans.ja = apps/susimail/locale/messages_ja.po
|
trans.ja = apps/susimail/locale/messages_ja.po
|
||||||
|
trans.ko = apps/susimail/locale/messages_ko.po
|
||||||
|
trans.mg = apps/susimail/locale/messages_mg.po
|
||||||
|
trans.nb = apps/susimail/locale/messages_nb.po
|
||||||
trans.nl = apps/susimail/locale/messages_nl.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.pl = apps/susimail/locale/messages_pl.po
|
||||||
trans.pt = apps/susimail/locale/messages_pt.po
|
trans.pt = apps/susimail/locale/messages_pt.po
|
||||||
trans.pt_BR = apps/susimail/locale/messages_pt_BR.po
|
trans.pt_BR = apps/susimail/locale/messages_pt_BR.po
|
||||||
trans.ro = apps/susimail/locale/messages_ro.po
|
trans.ro = apps/susimail/locale/messages_ro.po
|
||||||
|
trans.ru_RU = apps/susimail/locale/messages_ru.po
|
||||||
|
trans.sk = apps/susimail/locale/messages_sk.po
|
||||||
|
trans.sq = apps/susimail/locale/messages_sq.po
|
||||||
|
trans.sv_SE = apps/susimail/locale/messages_sv.po
|
||||||
|
trans.tr_TR = apps/susimail/locale/messages_tr.po
|
||||||
trans.uk_UA = apps/susimail/locale/messages_uk.po
|
trans.uk_UA = apps/susimail/locale/messages_uk.po
|
||||||
trans.vi = apps/susimail/locale/messages_vi.po
|
trans.vi = apps/susimail/locale/messages_vi.po
|
||||||
trans.zh_CN = apps/susimail/locale/messages_zh.po
|
trans.zh_CN = apps/susimail/locale/messages_zh.po
|
||||||
|
trans.zh_TW = apps/susimail/locale/messages_zh_TW.po
|
||||||
|
|
||||||
[I2P.debconf]
|
[I2P.debconf]
|
||||||
source_file = debian/po/templates.pot
|
source_file = debian/po/templates.pot
|
||||||
@@ -230,30 +290,41 @@ trans.cs = debian/po/cs.po
|
|||||||
trans.de = debian/po/de.po
|
trans.de = debian/po/de.po
|
||||||
trans.el = debian/po/el.po
|
trans.el = debian/po/el.po
|
||||||
trans.es = debian/po/es.po
|
trans.es = debian/po/es.po
|
||||||
|
trans.fi = debian/po/fi.po
|
||||||
trans.fr = debian/po/fr.po
|
trans.fr = debian/po/fr.po
|
||||||
|
trans.gl = debian/po/gl.po
|
||||||
|
trans.id = debian/po/id.po
|
||||||
trans.it = debian/po/it.po
|
trans.it = debian/po/it.po
|
||||||
trans.hu = debian/po/hu.po
|
trans.hu = debian/po/hu.po
|
||||||
trans.ja = debian/po/ja.po
|
trans.ja = debian/po/ja.po
|
||||||
trans.ko = debian/po/ko.po
|
trans.ko = debian/po/ko.po
|
||||||
|
trans.nl = debian/po/nl.po
|
||||||
trans.pl = debian/po/pl.po
|
trans.pl = debian/po/pl.po
|
||||||
trans.pt = debian/po/pt.po
|
trans.pt = debian/po/pt.po
|
||||||
|
trans.pt_BR = debian/po/pt_BR.po
|
||||||
trans.ro = debian/po/ro.po
|
trans.ro = debian/po/ro.po
|
||||||
trans.ru_RU = debian/po/ru.po
|
trans.ru_RU = debian/po/ru.po
|
||||||
trans.sk = debian/po/sk.po
|
trans.sk = debian/po/sk.po
|
||||||
|
trans.sq = debian/po/sq.po
|
||||||
trans.sv_SE = debian/po/sv.po
|
trans.sv_SE = debian/po/sv.po
|
||||||
trans.uk_UA = debian/po/uk.po
|
|
||||||
trans.tr_TR = debian/po/tr.po
|
trans.tr_TR = debian/po/tr.po
|
||||||
|
trans.uk_UA = debian/po/uk.po
|
||||||
trans.zh_CN = debian/po/zh.po
|
trans.zh_CN = debian/po/zh.po
|
||||||
|
trans.zh_TW = debian/po/zh_TW.po
|
||||||
|
|
||||||
[I2P.i2prouter-script]
|
[I2P.i2prouter-script]
|
||||||
source_file = installer/resources/locale/po/messages_en.po
|
source_file = installer/resources/locale/po/messages_en.po
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
trans.ca = installer/resources/locale/po/messages_ca.po
|
||||||
trans.de = installer/resources/locale/po/messages_de.po
|
trans.de = installer/resources/locale/po/messages_de.po
|
||||||
trans.es = installer/resources/locale/po/messages_es.po
|
trans.es = installer/resources/locale/po/messages_es.po
|
||||||
|
trans.fi = installer/resources/locale/po/messages_fi.po
|
||||||
trans.fr = installer/resources/locale/po/messages_fr.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.it = installer/resources/locale/po/messages_it.po
|
||||||
trans.pl = installer/resources/locale/po/messages_pl.po
|
|
||||||
trans.ja = installer/resources/locale/po/messages_ja.po
|
trans.ja = installer/resources/locale/po/messages_ja.po
|
||||||
|
trans.ko = installer/resources/locale/po/messages_ko.po
|
||||||
|
trans.nl = installer/resources/locale/po/messages_nl.po
|
||||||
trans.pl = installer/resources/locale/po/messages_pl.po
|
trans.pl = installer/resources/locale/po/messages_pl.po
|
||||||
trans.pt = installer/resources/locale/po/messages_pt.po
|
trans.pt = installer/resources/locale/po/messages_pt.po
|
||||||
trans.pt_BR = installer/resources/locale/po/messages_pt_BR.po
|
trans.pt_BR = installer/resources/locale/po/messages_pt_BR.po
|
||||||
@@ -262,6 +333,7 @@ trans.ru_RU = installer/resources/locale/po/messages_ru.po
|
|||||||
trans.sk = installer/resources/locale/po/messages_sk.po
|
trans.sk = installer/resources/locale/po/messages_sk.po
|
||||||
trans.sv_SE = installer/resources/locale/po/messages_sv.po
|
trans.sv_SE = installer/resources/locale/po/messages_sv.po
|
||||||
trans.tr_TR = installer/resources/locale/po/messages_tr.po
|
trans.tr_TR = installer/resources/locale/po/messages_tr.po
|
||||||
|
trans.uk_UA = installer/resources/locale/po/messages_uk.po
|
||||||
trans.zh_CN = installer/resources/locale/po/messages_zh.po
|
trans.zh_CN = installer/resources/locale/po/messages_zh.po
|
||||||
|
|
||||||
[I2P.getopt]
|
[I2P.getopt]
|
||||||
@@ -271,31 +343,78 @@ type = PROPERTIES
|
|||||||
trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties
|
trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties
|
||||||
trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
|
trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
|
||||||
trans.es = core/java/src/gnu/getopt/MessagesBundle_es.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.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties
|
||||||
|
;; currently corrupt, non-UTF-8
|
||||||
|
;;trans.gl = core/java/src/gnu/getopt/MessagesBundle_gl.properties
|
||||||
trans.hu = core/java/src/gnu/getopt/MessagesBundle_hu.properties
|
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.it = core/java/src/gnu/getopt/MessagesBundle_it.properties
|
||||||
trans.ja = core/java/src/gnu/getopt/MessagesBundle_ja.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.nl = core/java/src/gnu/getopt/MessagesBundle_nl.properties
|
||||||
trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties
|
trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties
|
||||||
trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties
|
trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties
|
||||||
trans.pt_BR = core/java/src/gnu/getopt/MessagesBundle_pt_BR.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.ro = core/java/src/gnu/getopt/MessagesBundle_ro.properties
|
||||||
trans.ru_RU = core/java/src/gnu/getopt/MessagesBundle_ru.properties
|
trans.ru_RU = core/java/src/gnu/getopt/MessagesBundle_ru.properties
|
||||||
trans.sk = core/java/src/gnu/getopt/MessagesBundle_sk.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
|
||||||
|
;; currently corrupt, non-UTF-8
|
||||||
|
;;trans.tr_TR = core/java/src/gnu/getopt/MessagesBundle_tr.properties
|
||||||
|
trans.uk_UA = core/java/src/gnu/getopt/MessagesBundle_uk.properties
|
||||||
trans.zh_CN = core/java/src/gnu/getopt/MessagesBundle_zh.properties
|
trans.zh_CN = core/java/src/gnu/getopt/MessagesBundle_zh.properties
|
||||||
|
|
||||||
[I2P.streaming]
|
[I2P.streaming]
|
||||||
source_file = apps/ministreaming/locale/messages_en.po
|
source_file = apps/ministreaming/locale/messages_en.po
|
||||||
source_lang = en
|
source_lang = en
|
||||||
|
trans.ca = apps/ministreaming/locale/messages_ca.po
|
||||||
|
trans.cs = apps/ministreaming/locale/messages_cs.po
|
||||||
trans.de = apps/ministreaming/locale/messages_de.po
|
trans.de = apps/ministreaming/locale/messages_de.po
|
||||||
trans.es = apps/ministreaming/locale/messages_es.po
|
trans.es = apps/ministreaming/locale/messages_es.po
|
||||||
|
trans.fi = apps/ministreaming/locale/messages_fi.po
|
||||||
trans.fr = apps/ministreaming/locale/messages_fr.po
|
trans.fr = apps/ministreaming/locale/messages_fr.po
|
||||||
|
trans.gl = apps/ministreaming/locale/messages_gl.po
|
||||||
|
;; Java converts id to in
|
||||||
|
trans.id = apps/ministreaming/locale/messages_in.po
|
||||||
trans.it = apps/ministreaming/locale/messages_it.po
|
trans.it = apps/ministreaming/locale/messages_it.po
|
||||||
|
trans.ko = apps/ministreaming/locale/messages_ko.po
|
||||||
trans.nb = apps/ministreaming/locale/messages_nb.po
|
trans.nb = apps/ministreaming/locale/messages_nb.po
|
||||||
|
trans.nl = apps/ministreaming/locale/messages_nl.po
|
||||||
|
trans.pl = apps/ministreaming/locale/messages_pl.po
|
||||||
|
trans.pt = apps/ministreaming/locale/messages_pt.po
|
||||||
|
trans.pt_BR = apps/ministreaming/locale/messages_pt_BR.po
|
||||||
|
trans.ro = apps/ministreaming/locale/messages_ro.po
|
||||||
trans.ru_RU = apps/ministreaming/locale/messages_ru.po
|
trans.ru_RU = apps/ministreaming/locale/messages_ru.po
|
||||||
|
trans.sv_SE = apps/ministreaming/locale/messages_sv.po
|
||||||
|
trans.tr_TR = apps/ministreaming/locale/messages_tr.po
|
||||||
trans.uk_UA = apps/ministreaming/locale/messages_uk.po
|
trans.uk_UA = apps/ministreaming/locale/messages_uk.po
|
||||||
trans.zh_CN = apps/ministreaming/locale/messages_zh.po
|
trans.zh_CN = apps/ministreaming/locale/messages_zh.po
|
||||||
|
|
||||||
|
[I2P.manpages]
|
||||||
|
type = PO
|
||||||
|
source_file = installer/resources/locale-man/man.pot
|
||||||
|
source_lang = en
|
||||||
|
; after adding languages here, add to debian/*.manpages also
|
||||||
|
trans.de = installer/resources/locale-man/man_de.po
|
||||||
|
trans.es = installer/resources/locale-man/man_es.po
|
||||||
|
trans.fi = installer/resources/locale-man/man_fi.po
|
||||||
|
trans.fr = installer/resources/locale-man/man_fr.po
|
||||||
|
trans.it = installer/resources/locale-man/man_it.po
|
||||||
|
trans.ko = installer/resources/locale-man/man_ko.po
|
||||||
|
trans.nl = installer/resources/locale-man/man_nl.po
|
||||||
|
trans.pl = installer/resources/locale-man/man_pl.po
|
||||||
|
trans.pt = installer/resources/locale-man/man_pt.po
|
||||||
|
trans.pt_BR = installer/resources/locale-man/man_pt_BR.po
|
||||||
|
trans.ru_RU = installer/resources/locale-man/man_ru.po
|
||||||
|
trans.sv_SE = installer/resources/locale-man/man_sv.po
|
||||||
|
trans.zh_CN = installer/resources/locale-man/man_zh.po
|
||||||
|
|
||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
|
|
||||||
|
|||||||
14
Docker.entrypoint.sh
Normal file
14
Docker.entrypoint.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export JAVA_HOME=/opt/jdk/jre
|
||||||
|
|
||||||
|
# Ensure user rights
|
||||||
|
chown -R i2p:nobody /opt/i2p
|
||||||
|
chmod -R u+rwx /opt/i2p
|
||||||
|
|
||||||
|
gosu i2p /opt/i2p/i2psvc /opt/i2p/wrapper.config wrapper.pidfile=/var/tmp/i2p.pid \
|
||||||
|
wrapper.name=i2p \
|
||||||
|
wrapper.displayname="I2P Service" \
|
||||||
|
wrapper.statusfile=/var/tmp/i2p.status \
|
||||||
|
wrapper.java.statusfile=/var/tmp/i2p.java.status \
|
||||||
|
wrapper.logfile=/var/tmp/wrapper.log
|
||||||
7
Docker.expt
Normal file
7
Docker.expt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/expect
|
||||||
|
set timeout 15;
|
||||||
|
spawn java -jar /tmp/i2pinstall.jar -console
|
||||||
|
expect {
|
||||||
|
-re ".*press 1 to continue, 2 to quit, 3 to redisplay" {send "1\r"; exp_continue;}
|
||||||
|
-re "Select target path *" {send "/opt/i2p\r"; exp_continue;}
|
||||||
|
}
|
||||||
62
Dockerfile
Normal file
62
Dockerfile
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
FROM meeh/java8server:latest
|
||||||
|
# Docker image based on Alpine with Java.
|
||||||
|
|
||||||
|
# We use Oracle Java to run I2P, but uses the openjdk to build it.
|
||||||
|
|
||||||
|
|
||||||
|
MAINTAINER Mikal Villa <mikal@sigterm.no>
|
||||||
|
|
||||||
|
ENV GIT_BRANCH="master"
|
||||||
|
ENV I2P_PREFIX="/opt/i2p"
|
||||||
|
ENV PATH=${I2P_PREFIX}/bin:$PATH
|
||||||
|
ENV JAVA_HOME=/usr/lib/jvm/default-jvm
|
||||||
|
|
||||||
|
ENV GOSU_VERSION=1.7
|
||||||
|
ENV GOSU_SHASUM="34049cfc713e8b74b90d6de49690fa601dc040021980812b2f1f691534be8a50 /usr/local/bin/gosu"
|
||||||
|
|
||||||
|
RUN mkdir /user && adduser -S -h /user i2p && chown -R i2p:nobody /user
|
||||||
|
|
||||||
|
# Adding files first, since Docker.expt is required for installation
|
||||||
|
ADD Docker.expt /tmp/Docker.expt
|
||||||
|
ADD Docker.entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
# Required for wget https
|
||||||
|
RUN apk add --no-cache openssl
|
||||||
|
# Gosu is a replacement for su/sudo in docker and not a backdoor :) See https://github.com/tianon/gosu
|
||||||
|
RUN wget -O /usr/local/bin/gosu https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64 \
|
||||||
|
&& echo "${GOSU_SHASUM}" | sha256sum -c && chmod +x /usr/local/bin/gosu
|
||||||
|
|
||||||
|
#
|
||||||
|
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
||||||
|
# image under 200mb we need to remove all the build dependencies in the same "RUN" / layer.
|
||||||
|
#
|
||||||
|
|
||||||
|
# The main layer
|
||||||
|
RUN apk --no-cache add build-base git gettext tar bzip2 apache-ant openjdk8 expect \
|
||||||
|
&& mkdir -p /usr/src/build \
|
||||||
|
&& cd /usr/src/build \
|
||||||
|
&& git clone -b ${GIT_BRANCH} https://github.com/i2p/i2p.i2p.git \
|
||||||
|
&& cd /usr/src/build/i2p.i2p \
|
||||||
|
&& echo "noExe=true" >> build.properties \
|
||||||
|
&& ant installer-linux \
|
||||||
|
&& cp i2pinstall*.jar /tmp/i2pinstall.jar \
|
||||||
|
&& mkdir -p /opt \
|
||||||
|
&& chown i2p:root /opt \
|
||||||
|
&& chmod u+rw /opt \
|
||||||
|
&& gosu i2p expect -f /tmp/Docker.expt \
|
||||||
|
&& cd ${I2P_PREFIX} \
|
||||||
|
&& rm -fr man docs *.bat *.command *.app /tmp/i2pinstall.jar /tmp/Docker.expt \
|
||||||
|
&& rm -fr /usr/src/build \
|
||||||
|
&& apk --purge del build-base apache-ant expect tcl expat git openjdk8 openjdk8-jre openjdk8-jre-base openjdk8-jre-lib bzip2 tar \
|
||||||
|
binutils-libs binutils pkgconfig libcurl libc-dev musl-dev g++ make fortify-headers pkgconf giflib libssh2 libxdmcp libxcb \
|
||||||
|
libx11 pcre alsa-lib libxi libxrender libxml2 readline bash openssl \
|
||||||
|
&& rm -fr /usr/lib/jvm/default-jre \
|
||||||
|
&& ln -sf /opt/jdk/jre /usr/lib/jvm/default-jre \
|
||||||
|
&& chmod a+x /entrypoint.sh
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EXPOSE 7654 7656 7657 7658 4444 6668 8998 7659 7660 4445 15000-20000
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ you may use:
|
|||||||
lynx http://localhost:7657/
|
lynx http://localhost:7657/
|
||||||
to configure the router.
|
to configure the router.
|
||||||
|
|
||||||
If you're having trouble, swing by http://forum.i2p/, check the
|
If you're having trouble, check the
|
||||||
website at https://geti2p.net/, 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 will create and store files and configuration data in the user directory
|
||||||
@@ -25,21 +25,22 @@ where there are comments labeled "PORTABLE". Do this before you
|
|||||||
run I2P for the first time.
|
run I2P for the first time.
|
||||||
|
|
||||||
To start I2P:
|
To start I2P:
|
||||||
(*nix): sh i2prouter start
|
(*nix, BSD, Mac): sh i2prouter start
|
||||||
(win*): I2P.exe
|
(win*): I2P.exe
|
||||||
(non-x86 platforms PPC, ARM, etc): sh runplain.sh
|
(platforms without wrapper support): sh runplain.sh
|
||||||
|
|
||||||
To stop I2P (gracefully):
|
To stop I2P (gracefully):
|
||||||
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
||||||
|
or (*nix, BSD, Mac) sh i2prouter graceful
|
||||||
|
|
||||||
To stop I2P immediately:
|
To stop I2P immediately:
|
||||||
sh i2prouter stop
|
(*nix, BSD, Mac) sh i2prouter stop
|
||||||
|
|
||||||
To uninstall I2P:
|
To uninstall I2P:
|
||||||
rm -rf $I2PInstallDir ~/.i2p
|
rm -rf $I2PInstallDir ~/.i2p
|
||||||
|
|
||||||
Supported JVMs:
|
Supported JVMs:
|
||||||
All platforms: Java 1.6 or higher required; 1.7 or higher recommended
|
All platforms: Java 1.7 or higher required
|
||||||
Windows: OpenJDK or Oracle from http://java.com/download
|
Windows: OpenJDK or Oracle from http://java.com/download
|
||||||
Linux: 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
|
FreeBSD: OpenJDK or Oracle from http://java.com/download
|
||||||
|
|||||||
23
INSTALL.txt
23
INSTALL.txt
@@ -1,11 +1,13 @@
|
|||||||
I2P source installation instructions
|
I2P source installation instructions
|
||||||
|
|
||||||
Prerequisites to build from source:
|
Prerequisites to build from source:
|
||||||
Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
|
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
|
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
|
Apache Ant 1.7.0 or higher
|
||||||
The xgettext, msgfmt, and msgmerge tools installed
|
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
|
To build and install I2P from source, you must first build
|
||||||
and package up the appropriate installer by running:
|
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.
|
Or move the i2pupdate.zip file into an existing installation directory and restart.
|
||||||
|
|
||||||
To start I2P:
|
To start I2P:
|
||||||
(*nix): sh i2prouter start
|
(*nix, BSD, Mac): sh i2prouter start
|
||||||
(win*): I2P.exe or i2prouter.bat
|
(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:
|
To install I2P as a system service:
|
||||||
(*nix) sh i2prouter install
|
(*nix, BSD, Mac) sh i2prouter install
|
||||||
(win*) install_i2p_service_winnt.bat
|
(win*) install_i2p_service_winnt.bat
|
||||||
|
|
||||||
To uninstall I2P as a system service:
|
To uninstall I2P as a system service:
|
||||||
(*nix) sh i2prouter remove
|
(*nix, BSD, Mac) sh i2prouter remove
|
||||||
(win*) uninstall_i2p-service_winnt.bat
|
(win*) uninstall_i2p-service_winnt.bat
|
||||||
|
|
||||||
To stop I2P (gracefully):
|
To stop I2P (gracefully):
|
||||||
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
lynx http://localhost:7657/summaryframe (click "Shutdown")
|
||||||
|
or (*nix, BSD, Mac) sh i2prouter graceful
|
||||||
|
|
||||||
To stop I2P immediately:
|
To stop I2P immediately:
|
||||||
sh i2prouter stop
|
(*nix, BSD, Mac) sh i2prouter stop
|
||||||
|
|
||||||
To uninstall I2P:
|
To uninstall I2P:
|
||||||
rm -rf $I2PInstallDir ~/.i2p
|
rm -rf $I2PInstallDir ~/.i2p
|
||||||
|
|
||||||
Supported JVMs:
|
Supported JVMs:
|
||||||
Windows: Latest available from http://java.com/download (1.5+ supported)
|
Windows: Latest available from http://java.com/download (1.7+ supported)
|
||||||
Linux: Latest available from http://java.com/download (1.5+ supported)
|
Linux: Latest available from http://java.com/download (1.7+ supported)
|
||||||
FreeBSD: 1.5-compatible (NIO required)
|
FreeBSD: 1.7-compatible (NIO required)
|
||||||
Other operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
Other operating systems and JVMs: See http://trac.i2p2.de/wiki/java
|
||||||
|
|||||||
61
LICENSE.txt
61
LICENSE.txt
@@ -36,10 +36,14 @@ Public domain except as listed below:
|
|||||||
Copyright (c) 2003, TheCrypto
|
Copyright (c) 2003, TheCrypto
|
||||||
See licenses/LICENSE-ElGamalDSA.txt
|
See licenses/LICENSE-ElGamalDSA.txt
|
||||||
|
|
||||||
SHA256 and HMAC:
|
HMAC:
|
||||||
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
|
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
|
||||||
See licenses/LICENSE-SHA256.txt
|
See licenses/LICENSE-SHA256.txt
|
||||||
|
|
||||||
|
ElGamal:
|
||||||
|
Copyright (c) 2000 - 2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||||
|
See licenses/LICENSE-SHA256.txt
|
||||||
|
|
||||||
AES code:
|
AES code:
|
||||||
Copyright (c) 1995-2005 The Cryptix Foundation Limited.
|
Copyright (c) 1995-2005 The Cryptix Foundation Limited.
|
||||||
See licenses/LICENSE-Cryptix.txt
|
See licenses/LICENSE-Cryptix.txt
|
||||||
@@ -54,13 +58,13 @@ Public domain except as listed below:
|
|||||||
|
|
||||||
PRNG:
|
PRNG:
|
||||||
Copyright (C) 2001, 2002, Free Software Foundation, Inc.
|
Copyright (C) 2001, 2002, Free Software Foundation, Inc.
|
||||||
See licenses/LICENSE-LGPLv2.1.txt
|
See licenses/LICENSE-LGPLv2.1.txt or /usr/share/common-licenses/LGPL-2.1
|
||||||
|
|
||||||
HashCash code:
|
HashCash code:
|
||||||
Copyright 2006 Gregory Rubin grrubin@gmail.com
|
Copyright 2006 Gregory Rubin grrubin@gmail.com
|
||||||
See licenses/LICENSE-HashCash.txt
|
See licenses/LICENSE-HashCash.txt
|
||||||
|
|
||||||
GettextResource from gettext v0.18:
|
GettextResource from gettext v0.19.8:
|
||||||
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
|
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
|
||||||
See licenses/LICENSE-LGPLv2.1.txt
|
See licenses/LICENSE-LGPLv2.1.txt
|
||||||
|
|
||||||
@@ -80,6 +84,10 @@ Public domain except as listed below:
|
|||||||
Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
|
Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
|
||||||
See licenses/LICENSE-LGPLv2.1.txt
|
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):
|
Router (router.jar):
|
||||||
Public domain except as listed below:
|
Public domain except as listed below:
|
||||||
@@ -87,7 +95,7 @@ Public domain except as listed below:
|
|||||||
From freenet
|
From freenet
|
||||||
See licenses/LICENSE-GPLv2.txt
|
See licenses/LICENSE-GPLv2.txt
|
||||||
|
|
||||||
UPnP subsystem (CyberLink) 2.1:
|
UPnP subsystem (CyberLink) 3.0:
|
||||||
Copyright (C) 2003-2010 Satoshi Konno
|
Copyright (C) 2003-2010 Satoshi Konno
|
||||||
See licenses/LICENSE-UPnP.txt
|
See licenses/LICENSE-UPnP.txt
|
||||||
|
|
||||||
@@ -95,9 +103,14 @@ Public domain except as listed below:
|
|||||||
http://creativecommons.org/licenses/by-sa/3.0/
|
http://creativecommons.org/licenses/by-sa/3.0/
|
||||||
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/
|
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/
|
||||||
|
|
||||||
|
GeoIP API 1.3.1:
|
||||||
|
See licenses/LICENSE-LGPLv2.1.txt
|
||||||
|
|
||||||
|
|
||||||
Installer:
|
Installer:
|
||||||
Launch4j 3.0.1:
|
Launch4j 3.0.1:
|
||||||
|
(Launch4j is only included in the upstream source package and Windows binaries.
|
||||||
|
Not applicable for non-Windows binaries or Debian/Launchpad packages.)
|
||||||
Copyright (c) 2004, 2008 Grzegorz Kowal
|
Copyright (c) 2004, 2008 Grzegorz Kowal
|
||||||
See licenses/LICENSE-Launch4j.txt (in binary packages)
|
See licenses/LICENSE-Launch4j.txt (in binary packages)
|
||||||
See installer/lib/launch4j/LICENSE.txt (in source packages)
|
See installer/lib/launch4j/LICENSE.txt (in source packages)
|
||||||
@@ -137,8 +150,8 @@ Installer:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Java Service Wrapper Community Edition 32-bit 3.5.25:
|
Java Service Wrapper Community Edition 32-bit 3.5.30:
|
||||||
Copyright (C) 1999-2011 Tanuki Software, Ltd. All Rights Reserved.
|
Copyright (C) 1999-2016 Tanuki Software, Ltd. All Rights Reserved.
|
||||||
See licenses/LICENSE-Wrapper.txt
|
See licenses/LICENSE-Wrapper.txt
|
||||||
|
|
||||||
|
|
||||||
@@ -148,6 +161,8 @@ Jbigi Libraries (jbigi.jar):
|
|||||||
GMP 4.3.2 / 5.0.2:
|
GMP 4.3.2 / 5.0.2:
|
||||||
Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
|
Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
|
||||||
See licenses/LICENSE-LGPLv3.txt
|
See licenses/LICENSE-LGPLv3.txt
|
||||||
|
GMP 6.0.0:
|
||||||
|
See licenses/LICENSE-GPLv2.txt
|
||||||
|
|
||||||
|
|
||||||
Applications:
|
Applications:
|
||||||
@@ -160,6 +175,10 @@ Applications:
|
|||||||
Copyright (C) sponge
|
Copyright (C) sponge
|
||||||
See licenses/COPYING-BOB.txt
|
See licenses/COPYING-BOB.txt
|
||||||
|
|
||||||
|
Desktopgui
|
||||||
|
Copyright (c) Mathias De Maré
|
||||||
|
See licenses/LICENSE-DesktopGUI.txt
|
||||||
|
|
||||||
I2PSnark:
|
I2PSnark:
|
||||||
Copyright (C) 2003 Mark J. Wielaard
|
Copyright (C) 2003 Mark J. Wielaard
|
||||||
GPLv2 (or any later version)
|
GPLv2 (or any later version)
|
||||||
@@ -182,15 +201,30 @@ Applications:
|
|||||||
By welterde.
|
By welterde.
|
||||||
See licenses/LICENSE-GPLv2.txt
|
See licenses/LICENSE-GPLv2.txt
|
||||||
|
|
||||||
Jetty 8.1.16.v20140903:
|
Imagegen:
|
||||||
|
Identicon:
|
||||||
|
Copyright (c) 2007-2014 Don Park <donpark@docuverse.com>
|
||||||
|
See licenses/LICENSE-Identicon.txt
|
||||||
|
RandomArt:
|
||||||
|
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
|
Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||||
|
See licenses/LICENSE-BSD.txt
|
||||||
|
Zxing 3.3.0:
|
||||||
|
See licenses/LICENSE-Apache2.0.txt
|
||||||
|
|
||||||
|
Jetty 9.2.21.v20170120:
|
||||||
See licenses/ABOUT-Jetty.html
|
See licenses/ABOUT-Jetty.html
|
||||||
See licenses/NOTICE-Jetty.html
|
See licenses/NOTICE-Jetty.html
|
||||||
See licenses/LICENSE-Apache2.0.txt
|
See licenses/LICENSE-Apache2.0.txt
|
||||||
See licenses/LICENSE-ECLIPSE-1.0.html
|
See licenses/LICENSE-ECLIPSE-1.0.html
|
||||||
See licenses/NOTICE-Commons-Logging.txt
|
|
||||||
|
|
||||||
JRobin 1.5.9.1:
|
JRobin 1.6.0-1:
|
||||||
|
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
|
||||||
|
Copyright (c) 2011 The OpenNMS Group, Inc.
|
||||||
See licenses/LICENSE-LGPLv2.1.txt
|
See licenses/LICENSE-LGPLv2.1.txt
|
||||||
|
DeallocationHelper:
|
||||||
|
Copyright (c) 2006-2016 Julien Gouesse
|
||||||
|
See licenses/LICENSE-GPLv2.txt
|
||||||
|
|
||||||
Ministreaming Lib:
|
Ministreaming Lib:
|
||||||
By mihi.
|
By mihi.
|
||||||
@@ -210,6 +244,7 @@ Applications:
|
|||||||
- All other flag icons: public domain, courtesy mjames@gmail.com http://www.famfamfam.com/
|
- All other flag icons: public domain, courtesy mjames@gmail.com http://www.famfamfam.com/
|
||||||
Silk icons: See licenses/LICENSE-SilkIcons.txt
|
Silk icons: See licenses/LICENSE-SilkIcons.txt
|
||||||
FatCow icons: See licenses/LICENSE-FatCowIcons.txt
|
FatCow icons: See licenses/LICENSE-FatCowIcons.txt
|
||||||
|
Fugue Icons: See licenses/LICENSE-FugueIcons.txt
|
||||||
|
|
||||||
GeoIP Data:
|
GeoIP Data:
|
||||||
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/
|
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/
|
||||||
@@ -248,8 +283,8 @@ Applications:
|
|||||||
Bundles systray4j-2.4.1:
|
Bundles systray4j-2.4.1:
|
||||||
See licenses/LICENSE-LGPLv2.1.txt
|
See licenses/LICENSE-LGPLv2.1.txt
|
||||||
|
|
||||||
Tomcat 6.0.41:
|
Tomcat 8.0.33:
|
||||||
Copyright 1999-2014 The Apache Software Foundation
|
Copyright 1999-2016 The Apache Software Foundation
|
||||||
See licenses/LICENSE-Apache2.0.txt
|
See licenses/LICENSE-Apache2.0.txt
|
||||||
See licenses/NOTICE-Tomcat.txt
|
See licenses/NOTICE-Tomcat.txt
|
||||||
|
|
||||||
@@ -267,10 +302,6 @@ distributions. See the source package for the additional license information.
|
|||||||
Copyright (C) sponge
|
Copyright (C) sponge
|
||||||
DWTFYWTPL
|
DWTFYWTPL
|
||||||
|
|
||||||
Desktopgui
|
|
||||||
Copyright (c) Mathias De Maré
|
|
||||||
See apps/desktopgui/LICENSE
|
|
||||||
|
|
||||||
SAM C Library:
|
SAM C Library:
|
||||||
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||||
See apps/sam/c/doc/license.txt
|
See apps/sam/c/doc/license.txt
|
||||||
|
|||||||
62
README.md
Normal file
62
README.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# I2P
|
||||||
|
|
||||||
|
This is the source code for the reference Java implementation of I2P.
|
||||||
|
|
||||||
|
Latest release: https://geti2p.net/download
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
See INSTALL.txt or https://geti2p.net/download for installation instructions.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
https://geti2p.net/how
|
||||||
|
|
||||||
|
FAQ: https://geti2p.net/faq
|
||||||
|
|
||||||
|
API: http://docs.i2p-projekt.de/javadoc/
|
||||||
|
or run 'ant javadoc' then start at build/javadoc/index.html
|
||||||
|
|
||||||
|
## Building packages from source
|
||||||
|
|
||||||
|
To get development branch from source control: https://geti2p.net/newdevelopers
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
### Build process
|
||||||
|
|
||||||
|
On x86 systems do:
|
||||||
|
|
||||||
|
ant pkg
|
||||||
|
|
||||||
|
On non-x86, use one of the following instead:
|
||||||
|
|
||||||
|
ant installer-linux
|
||||||
|
ant installer-freebsd
|
||||||
|
ant installer-osx
|
||||||
|
|
||||||
|
Run 'ant' with no arguments to see other build options.
|
||||||
|
|
||||||
|
## Contact info
|
||||||
|
|
||||||
|
Need help? See the IRC channel #i2p on irc.freenode.net
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
17
README.txt
17
README.txt
@@ -1,9 +1,11 @@
|
|||||||
Prerequisites to build from source:
|
Prerequisites to build from source:
|
||||||
Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
|
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
|
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
|
Apache Ant 1.7.0 or higher
|
||||||
The xgettext, msgfmt, and msgmerge tools installed
|
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:
|
To build:
|
||||||
On x86 systems do:
|
On x86 systems do:
|
||||||
@@ -19,7 +21,8 @@ To build:
|
|||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
https://geti2p.net/how
|
https://geti2p.net/how
|
||||||
API: run 'ant javadoc' then start at build/javadoc/index.html
|
API: http://docs.i2p-projekt.de/javadoc/
|
||||||
|
or run 'ant javadoc' then start at build/javadoc/index.html
|
||||||
|
|
||||||
Latest release:
|
Latest release:
|
||||||
https://geti2p.net/download
|
https://geti2p.net/download
|
||||||
@@ -32,7 +35,15 @@ FAQ:
|
|||||||
|
|
||||||
Need help?
|
Need help?
|
||||||
IRC irc.freenode.net #i2p
|
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:
|
Licenses:
|
||||||
See LICENSE.txt
|
See LICENSE.txt
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ config /etc/rc.d/rc.i2p.new
|
|||||||
config $INST_DIR/wrapper.config.new
|
config $INST_DIR/wrapper.config.new
|
||||||
|
|
||||||
if [ -e /var/log/packages/i2p-base* ]; then
|
if [ -e /var/log/packages/i2p-base* ]; then
|
||||||
echo "Warning: This package supercedes the 'i2p-base' package." >&2
|
echo "Warning: This package supersedes the 'i2p-base' package." >&2
|
||||||
echo
|
echo
|
||||||
echo "You may want to 'removepkg i2p-base'" >&2
|
echo "You may want to 'removepkg i2p-base'" >&2
|
||||||
echo "and check the contents of /etc/rc.d/rc.local*" >&2
|
echo "and check the contents of /etc/rc.d/rc.local*" >&2
|
||||||
|
|||||||
13
apps/BOB/BOB.iml
Normal file
13
apps/BOB/BOB.iml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="core" />
|
||||||
|
<orderEntry type="module" module-name="ministreaming" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -66,7 +66,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
||||||
CMDout.write(s.getBytes());
|
CMDout.write(DataHelper.getUTF8(s));
|
||||||
CMDout.write('\n');
|
CMDout.write('\n');
|
||||||
CMDout.flush();
|
CMDout.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
static void wrtxt(OutputStream CMDout, String s) throws IOException {
|
||||||
CMDout.write(s.getBytes());
|
CMDout.write(DataHelper.getUTF8(s));
|
||||||
CMDout.write('\n');
|
CMDout.write('\n');
|
||||||
CMDout.flush();
|
CMDout.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ javac.classpath=\
|
|||||||
# Space-separated list of extra javac options
|
# Space-separated list of extra javac options
|
||||||
javac.compilerargs=
|
javac.compilerargs=
|
||||||
javac.deprecation=false
|
javac.deprecation=false
|
||||||
javac.source=1.5
|
javac.version=1.7
|
||||||
javac.target=1.5
|
javac.source=${javac.version}
|
||||||
|
javac.target=${javac.version}
|
||||||
javac.test.classpath=\
|
javac.test.classpath=\
|
||||||
${javac.classpath}:\
|
${javac.classpath}:\
|
||||||
${build.classes.dir}:\
|
${build.classes.dir}:\
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import net.i2p.I2PAppContext;
|
|||||||
import net.i2p.app.*;
|
import net.i2p.app.*;
|
||||||
import net.i2p.client.I2PClient;
|
import net.i2p.client.I2PClient;
|
||||||
import net.i2p.util.I2PAppThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.SimpleScheduler;
|
|
||||||
import net.i2p.util.SimpleTimer2;
|
import net.i2p.util.SimpleTimer2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,6 +143,7 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
* Stop BOB gracefully
|
* Stop BOB gracefully
|
||||||
* @deprecated unused
|
* @deprecated unused
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public synchronized static void stop() {
|
public synchronized static void stop() {
|
||||||
if (_bob != null)
|
if (_bob != null)
|
||||||
_bob.shutdown(null);
|
_bob.shutdown(null);
|
||||||
@@ -155,7 +155,6 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
*
|
*
|
||||||
* @param mgr may be null
|
* @param mgr may be null
|
||||||
* @param args non-null
|
* @param args non-null
|
||||||
* @throws Exception on bad args
|
|
||||||
* @since 0.9.10
|
* @since 0.9.10
|
||||||
*/
|
*/
|
||||||
public BOB(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
public BOB(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
||||||
@@ -165,7 +164,7 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
if (classResource != null) {
|
if (classResource != null) {
|
||||||
String classPath = classResource.toString();
|
String classPath = classResource.toString();
|
||||||
if (classPath.startsWith("jar")) {
|
if (classPath.startsWith("jar")) {
|
||||||
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
|
String manifestPath = classPath.substring(0, classPath.lastIndexOf('!') + 1) +
|
||||||
"/META-INF/MANIFEST.MF";
|
"/META-INF/MANIFEST.MF";
|
||||||
try {
|
try {
|
||||||
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
|
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
|
||||||
@@ -214,9 +213,7 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
// Re-reading the config file in each thread is pretty damn stupid.
|
// Re-reading the config file in each thread is pretty damn stupid.
|
||||||
String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config");
|
String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config");
|
||||||
// This is here just to ensure there is no interference with our threadgroups.
|
// This is here just to ensure there is no interference with our threadgroups.
|
||||||
SimpleScheduler Y1 = SimpleScheduler.getInstance();
|
|
||||||
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
||||||
i = Y1.hashCode();
|
|
||||||
i = Y2.hashCode();
|
i = Y2.hashCode();
|
||||||
{
|
{
|
||||||
File cfg = new File(configLocation);
|
File cfg = new File(configLocation);
|
||||||
@@ -250,11 +247,11 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
save = true;
|
save = true;
|
||||||
}
|
}
|
||||||
if (!props.containsKey("inbound.length")) {
|
if (!props.containsKey("inbound.length")) {
|
||||||
props.setProperty("inbound.length", "1");
|
props.setProperty("inbound.length", "3");
|
||||||
save = true;
|
save = true;
|
||||||
}
|
}
|
||||||
if (!props.containsKey("outbound.length")) {
|
if (!props.containsKey("outbound.length")) {
|
||||||
props.setProperty("outbound.length", "1");
|
props.setProperty("outbound.length", "3");
|
||||||
save = true;
|
save = true;
|
||||||
}
|
}
|
||||||
if (!props.containsKey("inbound.lengthVariance")) {
|
if (!props.containsKey("inbound.lengthVariance")) {
|
||||||
@@ -341,7 +338,7 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
|
|
||||||
if (g) {
|
if (g) {
|
||||||
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
|
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
|
||||||
Thread t = new Thread(conn_c);
|
Thread t = new I2PAppThread(conn_c);
|
||||||
t.setName("BOB.DoCMDS " + i);
|
t.setName("BOB.DoCMDS " + i);
|
||||||
t.start();
|
t.start();
|
||||||
i++;
|
i++;
|
||||||
@@ -366,25 +363,30 @@ public class BOB implements Runnable, ClientApp {
|
|||||||
// We could order them to stop, but that could cause nasty issues in the locks.
|
// We could order them to stop, but that could cause nasty issues in the locks.
|
||||||
visitAllThreads();
|
visitAllThreads();
|
||||||
database.getReadLock();
|
database.getReadLock();
|
||||||
int all = database.getcount();
|
|
||||||
database.releaseReadLock();
|
|
||||||
NamedDB nickinfo;
|
NamedDB nickinfo;
|
||||||
for (i = 0; i < all; i++) {
|
try {
|
||||||
database.getReadLock();
|
for (Object ndb : database.values()) {
|
||||||
nickinfo = (NamedDB) database.getnext(i);
|
nickinfo = (NamedDB) ndb;
|
||||||
nickinfo.getReadLock();
|
nickinfo.getReadLock();
|
||||||
if (nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) {
|
boolean released = false;
|
||||||
nickinfo.releaseReadLock();
|
try {
|
||||||
database.releaseReadLock();
|
if (nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) {
|
||||||
database.getWriteLock();
|
nickinfo.releaseReadLock();
|
||||||
nickinfo.getWriteLock();
|
released = true;
|
||||||
nickinfo.add(P_STOPPING, Boolean.valueOf(true));
|
nickinfo.getWriteLock();
|
||||||
nickinfo.releaseWriteLock();
|
try {
|
||||||
database.releaseWriteLock();
|
nickinfo.add(P_STOPPING, Boolean.TRUE);
|
||||||
} else {
|
} finally {
|
||||||
nickinfo.releaseReadLock();
|
nickinfo.releaseWriteLock();
|
||||||
database.releaseReadLock();
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (!released)
|
||||||
|
nickinfo.releaseReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
database.releaseReadLock();
|
||||||
}
|
}
|
||||||
changeState(STOPPED);
|
changeState(STOPPED);
|
||||||
_log.info("BOB is now stopped.");
|
_log.info("BOB is now stopped.");
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,10 +18,12 @@ package net.i2p.BOB;
|
|||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import net.i2p.I2PException;
|
import net.i2p.I2PException;
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
|
import net.i2p.util.I2PAppThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on I2P and connect to TCP
|
* Listen on I2P and connect to TCP
|
||||||
@@ -30,16 +32,15 @@ import net.i2p.client.streaming.I2PSocketManager;
|
|||||||
*/
|
*/
|
||||||
public class I2Plistener implements Runnable {
|
public class I2Plistener implements Runnable {
|
||||||
|
|
||||||
private NamedDB info, database;
|
private final NamedDB info, database;
|
||||||
private Logger _log;
|
private final Logger _log;
|
||||||
public I2PSocketManager socketManager;
|
private final I2PServerSocket serverSocket;
|
||||||
public I2PServerSocket serverSocket;
|
private final AtomicBoolean lives;
|
||||||
private AtomicBoolean lives;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param SS
|
* @param SS
|
||||||
* @param S
|
* @param S unused
|
||||||
* @param info
|
* @param info
|
||||||
* @param database
|
* @param database
|
||||||
* @param _log
|
* @param _log
|
||||||
@@ -48,7 +49,6 @@ public class I2Plistener implements Runnable {
|
|||||||
this.database = database;
|
this.database = database;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this._log = _log;
|
this._log = _log;
|
||||||
this.socketManager = S;
|
|
||||||
this.serverSocket = SS;
|
this.serverSocket = SS;
|
||||||
this.lives = lives;
|
this.lives = lives;
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ public class I2Plistener implements Runnable {
|
|||||||
conn++;
|
conn++;
|
||||||
// toss the connection to a new thread.
|
// toss the connection to a new thread.
|
||||||
I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives);
|
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();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,19 +19,22 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
import net.i2p.util.I2PAppThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process I2P->TCP
|
* Process I2P->TCP
|
||||||
*
|
*
|
||||||
* @author sponge
|
* @author sponge
|
||||||
*/
|
*/
|
||||||
public class I2PtoTCP implements Runnable {
|
public class I2PtoTCP implements Runnable {
|
||||||
|
|
||||||
private I2PSocket I2P;
|
private I2PSocket I2P;
|
||||||
private NamedDB info, database;
|
private final NamedDB info, database;
|
||||||
private Socket sock;
|
private Socket sock;
|
||||||
private AtomicBoolean lives;
|
private final AtomicBoolean lives;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -53,8 +56,8 @@ public class I2PtoTCP implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runlock() {
|
private void runlock() {
|
||||||
database.releaseReadLock();
|
|
||||||
info.releaseReadLock();
|
info.releaseReadLock();
|
||||||
|
database.releaseReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,23 +78,15 @@ public class I2PtoTCP implements Runnable {
|
|||||||
die:
|
die:
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
try {
|
rlock();
|
||||||
rlock();
|
|
||||||
} catch (Exception e) {
|
|
||||||
break die;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
host = info.get("OUTHOST").toString();
|
host = info.get("OUTHOST").toString();
|
||||||
port = Integer.parseInt(info.get("OUTPORT").toString());
|
port = Integer.parseInt(info.get("OUTPORT").toString());
|
||||||
tell = info.get("QUIET").equals(Boolean.FALSE);
|
tell = info.get("QUIET").equals(Boolean.FALSE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
runlock();
|
|
||||||
break die;
|
break die;
|
||||||
}
|
} finally {
|
||||||
try {
|
|
||||||
runlock();
|
runlock();
|
||||||
} catch (Exception e) {
|
|
||||||
break die;
|
|
||||||
}
|
}
|
||||||
sock = new Socket(host, port);
|
sock = new Socket(host, port);
|
||||||
sock.setKeepAlive(true);
|
sock.setKeepAlive(true);
|
||||||
@@ -104,15 +99,15 @@ public class I2PtoTCP implements Runnable {
|
|||||||
|
|
||||||
if (tell) {
|
if (tell) {
|
||||||
// tell who is connecting
|
// tell who is connecting
|
||||||
out.write(I2P.getPeerDestination().toBase64().getBytes());
|
out.write(DataHelper.getASCII(I2P.getPeerDestination().toBase64()));
|
||||||
out.write(10); // nl
|
out.write(10); // nl
|
||||||
out.flush(); // not really needed, but...
|
out.flush(); // not really needed, but...
|
||||||
}
|
}
|
||||||
// setup to cross the streams
|
// setup to cross the streams
|
||||||
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
||||||
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
||||||
t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||||
q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||||
// Fire!
|
// Fire!
|
||||||
t.start();
|
t.start();
|
||||||
q.start();
|
q.start();
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ import java.net.InetAddress;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import net.i2p.I2PException;
|
import net.i2p.I2PException;
|
||||||
import net.i2p.client.I2PClient;
|
import net.i2p.client.I2PClient;
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||||
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,18 +38,18 @@ import net.i2p.util.Log;
|
|||||||
*/
|
*/
|
||||||
public class MUXlisten implements Runnable {
|
public class MUXlisten implements Runnable {
|
||||||
|
|
||||||
private NamedDB database, info;
|
private final NamedDB database, info;
|
||||||
private Logger _log;
|
private final Logger _log;
|
||||||
private I2PSocketManager socketManager;
|
private final I2PSocketManager socketManager;
|
||||||
private ByteArrayInputStream prikey;
|
private final ByteArrayInputStream prikey;
|
||||||
private ThreadGroup tg;
|
private ThreadGroup tg;
|
||||||
private String N;
|
private final String N;
|
||||||
private ServerSocket listener = null;
|
private ServerSocket listener;
|
||||||
private int backlog = 50; // should this be more? less?
|
private final int backlog = 50; // should this be more? less?
|
||||||
boolean go_out;
|
private final boolean go_out;
|
||||||
boolean come_in;
|
private final boolean come_in;
|
||||||
private AtomicBoolean lock;
|
private final AtomicBoolean lock;
|
||||||
private AtomicBoolean lives;
|
private final AtomicBoolean lives;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor Will fail if INPORT is occupied.
|
* Constructor Will fail if INPORT is occupied.
|
||||||
@@ -59,43 +61,39 @@ public class MUXlisten implements Runnable {
|
|||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
MUXlisten(AtomicBoolean lock, NamedDB database, NamedDB info, Logger _log) throws I2PException, IOException, RuntimeException {
|
MUXlisten(AtomicBoolean lock, NamedDB database, NamedDB info, Logger _log) throws I2PException, IOException, RuntimeException {
|
||||||
|
int port = 0;
|
||||||
|
InetAddress host = null;
|
||||||
|
this.lock = lock;
|
||||||
|
this.tg = null;
|
||||||
|
this.database = database;
|
||||||
|
this.info = info;
|
||||||
|
this._log = _log;
|
||||||
|
lives = new AtomicBoolean(false);
|
||||||
try {
|
try {
|
||||||
int port = 0;
|
wlock();
|
||||||
InetAddress host = null;
|
try {
|
||||||
this.lock = lock;
|
this.info.add("STARTING", Boolean.TRUE);
|
||||||
this.tg = null;
|
} finally {
|
||||||
this.database = database;
|
wunlock();
|
||||||
this.info = info;
|
}
|
||||||
this._log = _log;
|
Properties Q = new Properties();
|
||||||
lives = new AtomicBoolean(false);
|
rlock();
|
||||||
|
try {
|
||||||
this.database.getWriteLock();
|
N = this.info.get("NICKNAME").toString();
|
||||||
this.info.getWriteLock();
|
prikey = new ByteArrayInputStream((byte[]) info.get("KEYS"));
|
||||||
this.info.add("STARTING", Boolean.valueOf(true));
|
// Make a new copy so that anything else won't muck with our database.
|
||||||
this.info.releaseWriteLock();
|
Properties R = (Properties) info.get("PROPERTIES");
|
||||||
this.database.releaseWriteLock();
|
Lifted.copyProperties(R, Q);
|
||||||
this.database.getReadLock();
|
|
||||||
this.info.getReadLock();
|
this.go_out = info.exists("OUTPORT");
|
||||||
|
this.come_in = info.exists("INPORT");
|
||||||
N = this.info.get("NICKNAME").toString();
|
if (this.come_in) {
|
||||||
prikey = new ByteArrayInputStream((byte[]) info.get("KEYS"));
|
port = Integer.parseInt(info.get("INPORT").toString());
|
||||||
// Make a new copy so that anything else won't muck with our database.
|
host = InetAddress.getByName(info.get("INHOST").toString());
|
||||||
Properties R = (Properties) info.get("PROPERTIES");
|
}
|
||||||
Properties Q = new Properties();
|
} finally {
|
||||||
Lifted.copyProperties(R, Q);
|
runlock();
|
||||||
this.database.releaseReadLock();
|
|
||||||
this.info.releaseReadLock();
|
|
||||||
|
|
||||||
this.database.getReadLock();
|
|
||||||
this.info.getReadLock();
|
|
||||||
this.go_out = info.exists("OUTPORT");
|
|
||||||
this.come_in = info.exists("INPORT");
|
|
||||||
if (this.come_in) {
|
|
||||||
port = Integer.parseInt(info.get("INPORT").toString());
|
|
||||||
host = InetAddress.getByName(info.get("INHOST").toString());
|
|
||||||
}
|
}
|
||||||
this.database.releaseReadLock();
|
|
||||||
this.info.releaseReadLock();
|
|
||||||
|
|
||||||
String i2cpHost = Q.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
|
String i2cpHost = Q.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
|
||||||
int i2cpPort = 7654;
|
int i2cpPort = 7654;
|
||||||
@@ -113,48 +111,51 @@ public class MUXlisten implements Runnable {
|
|||||||
prikey, i2cpHost, i2cpPort, Q);
|
prikey, i2cpHost, i2cpPort, Q);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Something went bad.
|
// Something went bad.
|
||||||
this.database.getWriteLock();
|
wlock();
|
||||||
this.info.getWriteLock();
|
try {
|
||||||
this.info.add("STARTING", Boolean.valueOf(false));
|
this.info.add("STARTING", Boolean.FALSE);
|
||||||
this.info.releaseWriteLock();
|
} finally {
|
||||||
this.database.releaseWriteLock();
|
wunlock();
|
||||||
throw new IOException(e.toString());
|
}
|
||||||
|
throw e;
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// Something went bad.
|
// Something went bad.
|
||||||
this.database.getWriteLock();
|
wlock();
|
||||||
this.info.getWriteLock();
|
try {
|
||||||
this.info.add("STARTING", Boolean.valueOf(false));
|
this.info.add("STARTING", Boolean.FALSE);
|
||||||
this.info.releaseWriteLock();
|
} finally {
|
||||||
this.database.releaseWriteLock();
|
wunlock();
|
||||||
throw new RuntimeException(e);
|
}
|
||||||
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Something else went bad.
|
// Something else went bad.
|
||||||
this.database.getWriteLock();
|
wlock();
|
||||||
this.info.getWriteLock();
|
try {
|
||||||
this.info.add("STARTING", Boolean.valueOf(false));
|
this.info.add("STARTING", Boolean.FALSE);
|
||||||
this.info.releaseWriteLock();
|
} finally {
|
||||||
this.database.releaseWriteLock();
|
wunlock();
|
||||||
|
}
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rlock() throws Exception {
|
private void rlock() {
|
||||||
database.getReadLock();
|
database.getReadLock();
|
||||||
info.getReadLock();
|
info.getReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runlock() throws Exception {
|
private void runlock() {
|
||||||
database.releaseReadLock();
|
|
||||||
info.releaseReadLock();
|
info.releaseReadLock();
|
||||||
|
database.releaseReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void wlock() throws Exception {
|
private void wlock() {
|
||||||
database.getWriteLock();
|
database.getWriteLock();
|
||||||
info.getWriteLock();
|
info.getWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void wunlock() throws Exception {
|
private void wunlock() {
|
||||||
info.releaseWriteLock();
|
info.releaseWriteLock();
|
||||||
database.releaseWriteLock();
|
database.releaseWriteLock();
|
||||||
}
|
}
|
||||||
@@ -168,24 +169,19 @@ public class MUXlisten implements Runnable {
|
|||||||
Thread t = null;
|
Thread t = null;
|
||||||
Thread q = null;
|
Thread q = null;
|
||||||
try {
|
try {
|
||||||
|
wlock();
|
||||||
try {
|
try {
|
||||||
wlock();
|
|
||||||
try {
|
try {
|
||||||
info.add("RUNNING", Boolean.valueOf(true));
|
info.add("RUNNING", Boolean.TRUE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
lock.set(false);
|
lock.set(false);
|
||||||
wunlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
lock.set(false);
|
lock.set(false);
|
||||||
return;
|
return;
|
||||||
}
|
} finally {
|
||||||
try {
|
|
||||||
wunlock();
|
wunlock();
|
||||||
} catch (Exception e) {
|
|
||||||
lock.set(false);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
lives.set(true);
|
lives.set(true);
|
||||||
lock.set(false);
|
lock.set(false);
|
||||||
@@ -201,32 +197,28 @@ public class MUXlisten implements Runnable {
|
|||||||
// I2P -> TCP
|
// I2P -> TCP
|
||||||
SS = socketManager.getServerSocket();
|
SS = socketManager.getServerSocket();
|
||||||
I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log, lives);
|
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();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (come_in) {
|
if (come_in) {
|
||||||
// TCP -> I2P
|
// TCP -> I2P
|
||||||
TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log, lives);
|
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();
|
q.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlock();
|
||||||
try {
|
try {
|
||||||
wlock();
|
|
||||||
try {
|
try {
|
||||||
info.add("STARTING", Boolean.valueOf(false));
|
info.add("STARTING", Boolean.FALSE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
wunlock();
|
|
||||||
break quit;
|
break quit;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
break quit;
|
break quit;
|
||||||
}
|
} finally {
|
||||||
try {
|
|
||||||
wunlock();
|
wunlock();
|
||||||
} catch (Exception e) {
|
|
||||||
break quit;
|
|
||||||
}
|
}
|
||||||
boolean spin = true;
|
boolean spin = true;
|
||||||
while (spin && lives.get()) {
|
while (spin && lives.get()) {
|
||||||
@@ -235,21 +227,17 @@ public class MUXlisten implements Runnable {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
break quit;
|
break quit;
|
||||||
}
|
}
|
||||||
|
rlock();
|
||||||
try {
|
try {
|
||||||
rlock();
|
|
||||||
try {
|
try {
|
||||||
spin = info.get("STOPPING").equals(Boolean.FALSE);
|
spin = info.get("STOPPING").equals(Boolean.FALSE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
runlock();
|
|
||||||
break quit;
|
break quit;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
break quit;
|
break quit;
|
||||||
}
|
} finally {
|
||||||
try {
|
|
||||||
runlock();
|
runlock();
|
||||||
} catch (Exception e) {
|
|
||||||
break quit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // die
|
} // die
|
||||||
@@ -269,16 +257,16 @@ public class MUXlisten implements Runnable {
|
|||||||
try {
|
try {
|
||||||
wlock();
|
wlock();
|
||||||
try {
|
try {
|
||||||
info.add("STARTING", Boolean.valueOf(false));
|
info.add("STARTING", Boolean.FALSE);
|
||||||
info.add("STOPPING", Boolean.valueOf(true));
|
info.add("STOPPING", Boolean.TRUE);
|
||||||
info.add("RUNNING", Boolean.valueOf(false));
|
info.add("RUNNING", Boolean.FALSE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
lock.set(false);
|
lock.set(false);
|
||||||
wunlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wunlock();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
} finally {
|
||||||
|
wunlock();
|
||||||
}
|
}
|
||||||
// Start cleanup.
|
// Start cleanup.
|
||||||
while (!lock.compareAndSet(false, true)) {
|
while (!lock.compareAndSet(false, true)) {
|
||||||
@@ -320,15 +308,15 @@ public class MUXlisten implements Runnable {
|
|||||||
try {
|
try {
|
||||||
wlock();
|
wlock();
|
||||||
try {
|
try {
|
||||||
info.add("STARTING", Boolean.valueOf(false));
|
info.add("STARTING", Boolean.FALSE);
|
||||||
info.add("STOPPING", Boolean.valueOf(false));
|
info.add("STOPPING", Boolean.FALSE);
|
||||||
info.add("RUNNING", Boolean.valueOf(false));
|
info.add("RUNNING", Boolean.FALSE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
lock.set(false);
|
lock.set(false);
|
||||||
wunlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
} finally {
|
||||||
wunlock();
|
wunlock();
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package net.i2p.BOB;
|
package net.i2p.BOB;
|
||||||
|
|
||||||
import net.i2p.util.SimpleScheduler;
|
|
||||||
import net.i2p.util.SimpleTimer2;
|
import net.i2p.util.SimpleTimer2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,12 +30,10 @@ public class Main {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// THINK THINK THINK THINK THINK THINK
|
// THINK THINK THINK THINK THINK THINK
|
||||||
SimpleScheduler Y1 = SimpleScheduler.getInstance();
|
|
||||||
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
|
||||||
|
|
||||||
BOB.main(args);
|
BOB.main(args);
|
||||||
|
|
||||||
Y2.stop();
|
Y2.stop();
|
||||||
Y1.stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.i2p.BOB;
|
package net.i2p.BOB;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal database to relate nicknames to options to values
|
* Internal database to relate nicknames to options to values
|
||||||
*
|
*
|
||||||
@@ -22,129 +28,62 @@ package net.i2p.BOB;
|
|||||||
*/
|
*/
|
||||||
public class NamedDB {
|
public class NamedDB {
|
||||||
|
|
||||||
private volatile Object[][] data;
|
private final Map<String, Object> data;
|
||||||
private int index, writersWaiting, readers;
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* make initial NULL object
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public NamedDB() {
|
public NamedDB() {
|
||||||
this.data = new Object[1][2];
|
this.data = new HashMap<String, Object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void getReadLock() {
|
public void getReadLock() {
|
||||||
while ((writersWaiting != 0)) {
|
lock.readLock().lock();
|
||||||
try {
|
|
||||||
wait();
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readers++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void releaseReadLock() {
|
public void releaseReadLock() {
|
||||||
readers--;
|
lock.readLock().unlock();
|
||||||
notifyAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void getWriteLock() {
|
public void getWriteLock() {
|
||||||
writersWaiting++;
|
lock.writeLock().lock();
|
||||||
while (readers != 0 && writersWaiting != 1) {
|
|
||||||
try {
|
|
||||||
wait();
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void releaseWriteLock() {
|
public void releaseWriteLock() {
|
||||||
writersWaiting--;
|
lock.writeLock().unlock();
|
||||||
notifyAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find objects in the array, returns it's index or throws exception
|
* Delete an object if it exists
|
||||||
* @param key
|
|
||||||
* @return an objects index
|
|
||||||
* @throws ArrayIndexOutOfBoundsException when key does not exist
|
|
||||||
*/
|
|
||||||
public int idx(Object key) throws ArrayIndexOutOfBoundsException {
|
|
||||||
for (int i = 0; i < index; i++) {
|
|
||||||
if (key.equals(data[i][0])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new ArrayIndexOutOfBoundsException("Can't locate key for index");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an object from array if it exists
|
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
*/
|
*/
|
||||||
public void kill(Object key) {
|
public void kill(String key) {
|
||||||
|
data.remove(key);
|
||||||
int i, j, k, l;
|
|
||||||
Object[][] olddata;
|
|
||||||
int didsomething = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
k = idx(key);
|
|
||||||
} catch (ArrayIndexOutOfBoundsException b) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
olddata = new Object[index + 2][2];
|
|
||||||
// copy to olddata, skipping 'k'
|
|
||||||
for (i = 0, l = 0; l < index; i++, l++) {
|
|
||||||
if (i == k) {
|
|
||||||
l++;
|
|
||||||
didsomething++;
|
|
||||||
}
|
|
||||||
for (j = 0; j < 2; j++) {
|
|
||||||
olddata[i][j] = data[l][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index -= didsomething;
|
|
||||||
data = olddata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add object to the array, deletes the old one if it exists
|
* Add object, deletes the old one if it exists
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @param val
|
* @param val
|
||||||
*/
|
*/
|
||||||
public void add(Object key, Object val) {
|
public void add(String key, Object val) {
|
||||||
Object[][] olddata;
|
data.put(key, val);
|
||||||
int i, j;
|
|
||||||
i = 0;
|
|
||||||
kill(key);
|
|
||||||
|
|
||||||
olddata = new Object[index + 2][2];
|
|
||||||
// copy to olddata
|
|
||||||
for (i = 0; i < index; i++) {
|
|
||||||
for (j = 0; j < 2; j++) {
|
|
||||||
olddata[i][j] = data[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data = olddata;
|
|
||||||
data[index++] = new Object[]{key, val};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the object, and return it, throws RuntimeException
|
* Get the object, and return it, throws RuntimeException if not found
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key non-null
|
||||||
* @return Object
|
* @return Object non-null
|
||||||
* @throws java.lang.RuntimeException
|
* @throws java.lang.RuntimeException if not found
|
||||||
*/
|
*/
|
||||||
public Object get(Object key) throws RuntimeException {
|
public Object get(String key) throws RuntimeException {
|
||||||
for (int i = 0; i < index; i++) {
|
Object rv = data.get(key);
|
||||||
if (key.equals(data[i][0])) {
|
if (rv != null)
|
||||||
return data[i][1];
|
return rv;
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Key not found");
|
throw new RuntimeException("Key not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,33 +93,14 @@ public class NamedDB {
|
|||||||
* @param key
|
* @param key
|
||||||
* @return true if an object exists, else returns false
|
* @return true if an object exists, else returns false
|
||||||
*/
|
*/
|
||||||
public boolean exists(Object key) {
|
public boolean exists(String key) {
|
||||||
for (int i = 0; i < index; i++) {
|
return data.containsKey(key);
|
||||||
if (key.equals(data[i][0])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @since 0.9.29 replaces getcount() and getnext(int)
|
||||||
* @param i index
|
|
||||||
* @return an indexed Object
|
|
||||||
* @throws java.lang.RuntimeException
|
|
||||||
*/
|
*/
|
||||||
public Object getnext(int i) throws RuntimeException {
|
public Collection<Object> values() {
|
||||||
if (i < index && i > -1) {
|
return data.values();
|
||||||
return data[i][1];
|
|
||||||
}
|
|
||||||
throw new RuntimeException("No more data");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the count of how many objects
|
|
||||||
*/
|
|
||||||
public int getcount() {
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
*/
|
*/
|
||||||
public class TCPio implements Runnable {
|
public class TCPio implements Runnable {
|
||||||
|
|
||||||
private InputStream Ain;
|
private final InputStream Ain;
|
||||||
private OutputStream Aout;
|
private final OutputStream Aout;
|
||||||
private AtomicBoolean lives;
|
private final AtomicBoolean lives;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
|
import net.i2p.util.I2PAppThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on TCP port and connect to I2P
|
* Listen on TCP port and connect to I2P
|
||||||
@@ -30,12 +32,11 @@ import net.i2p.client.streaming.I2PSocketManager;
|
|||||||
*/
|
*/
|
||||||
public class TCPlistener implements Runnable {
|
public class TCPlistener implements Runnable {
|
||||||
|
|
||||||
private NamedDB info, database;
|
private final NamedDB info, database;
|
||||||
private Logger _log;
|
private final Logger _log;
|
||||||
public I2PSocketManager socketManager;
|
private final I2PSocketManager socketManager;
|
||||||
public I2PServerSocket serverSocket;
|
private final ServerSocket listener;
|
||||||
private ServerSocket listener;
|
private final AtomicBoolean lives;
|
||||||
private AtomicBoolean lives;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -76,7 +77,7 @@ public class TCPlistener implements Runnable {
|
|||||||
conn++;
|
conn++;
|
||||||
// toss the connection to a new thread.
|
// toss the connection to a new thread.
|
||||||
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
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();
|
t.start();
|
||||||
g = false;
|
g = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,39 +24,37 @@ import java.net.NoRouteToHostException;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.I2PException;
|
import net.i2p.I2PException;
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
//import net.i2p.i2ptunnel.I2PTunnel;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.I2PAppContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Process TCP->I2P
|
* Process TCP->I2P
|
||||||
*
|
*
|
||||||
* @author sponge
|
* @author sponge
|
||||||
*/
|
*/
|
||||||
public class TCPtoI2P implements Runnable {
|
public class TCPtoI2P implements Runnable {
|
||||||
|
|
||||||
private I2PSocket I2P;
|
private I2PSocket I2P;
|
||||||
private NamedDB info, database;
|
private final Socket sock;
|
||||||
private Socket sock;
|
private final I2PSocketManager socketManager;
|
||||||
private I2PSocketManager socketManager;
|
private final AtomicBoolean lives;
|
||||||
private AtomicBoolean lives;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param i2p
|
* @param i2p
|
||||||
* @param socket
|
* @param socket
|
||||||
* param info
|
* @param info unused
|
||||||
* param database
|
* @param database unused
|
||||||
*/
|
*/
|
||||||
TCPtoI2P(I2PSocketManager i2p, Socket socket, NamedDB info, NamedDB database, AtomicBoolean lives) {
|
TCPtoI2P(I2PSocketManager i2p, Socket socket, NamedDB info, NamedDB database, AtomicBoolean lives) {
|
||||||
this.sock = socket;
|
this.sock = socket;
|
||||||
this.info = info;
|
|
||||||
this.database = database;
|
|
||||||
this.socketManager = i2p;
|
this.socketManager = i2p;
|
||||||
this.lives = lives;
|
this.lives = lives;
|
||||||
}
|
}
|
||||||
@@ -105,16 +103,6 @@ public class TCPtoI2P implements Runnable {
|
|||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rlock() {
|
|
||||||
database.getReadLock();
|
|
||||||
info.getReadLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runlock() {
|
|
||||||
info.releaseReadLock();
|
|
||||||
database.releaseReadLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TCP stream to I2P stream thread starter
|
* TCP stream to I2P stream thread starter
|
||||||
*
|
*
|
||||||
@@ -158,8 +146,8 @@ public class TCPtoI2P implements Runnable {
|
|||||||
// setup to cross the streams
|
// setup to cross the streams
|
||||||
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
|
||||||
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
|
||||||
t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
|
||||||
q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
|
||||||
// Fire!
|
// Fire!
|
||||||
t.start();
|
t.start();
|
||||||
q.start();
|
q.start();
|
||||||
|
|||||||
@@ -34,15 +34,18 @@ import net.i2p.util.Log;
|
|||||||
* The skeletal frame is here, just needs to be finished.
|
* The skeletal frame is here, just needs to be finished.
|
||||||
*
|
*
|
||||||
* @author sponge
|
* @author sponge
|
||||||
|
* @deprecated incomplete, unused
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class UDPIOthread implements I2PSessionListener, Runnable {
|
public class UDPIOthread implements I2PSessionListener, Runnable {
|
||||||
|
|
||||||
private NamedDB info;
|
private final NamedDB info;
|
||||||
private Log _log;
|
private final Log _log;
|
||||||
private Socket socket;
|
private final Socket socket;
|
||||||
private DataInputStream in;
|
private DataInputStream in;
|
||||||
private DataOutputStream out;
|
private DataOutputStream out;
|
||||||
private I2PSession _session;
|
private final I2PSession _session;
|
||||||
|
// FIXME never set
|
||||||
private Destination _peerDestination;
|
private Destination _peerDestination;
|
||||||
private boolean up;
|
private boolean up;
|
||||||
|
|
||||||
@@ -58,7 +61,6 @@ public class UDPIOthread implements I2PSessionListener, Runnable {
|
|||||||
this._log = _log;
|
this._log = _log;
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this._session = _session;
|
this._session = _session;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
25
apps/addressbook/addressbook.iml
Normal file
25
apps/addressbook/addressbook.iml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="web" name="Web">
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web.xml" />
|
||||||
|
</descriptors>
|
||||||
|
<webroots>
|
||||||
|
<root url="file://$MODULE_DIR$" relative="/WEB-INF" />
|
||||||
|
</webroots>
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="jettylib" level="project" />
|
||||||
|
<orderEntry type="module" module-name="core" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<project name="addressbook" default="war" basedir=".">
|
<project name="addressbook" default="all" basedir=".">
|
||||||
|
|
||||||
<property name="src" value="java/src"/>
|
<property name="src" value="java/src"/>
|
||||||
<property name="build" value="build"/>
|
<property name="build" value="build"/>
|
||||||
@@ -7,7 +7,9 @@
|
|||||||
<property name="jar" value="addressbook.jar"/>
|
<property name="jar" value="addressbook.jar"/>
|
||||||
<property name="war" value="addressbook.war"/>
|
<property name="war" value="addressbook.war"/>
|
||||||
<property name="javac.compilerargs" value="" />
|
<property name="javac.compilerargs" value="" />
|
||||||
<property name="javac.version" value="1.6" />
|
<property name="javac.version" value="1.7" />
|
||||||
|
|
||||||
|
<target name="all" depends="jar, emptyWar"/>
|
||||||
|
|
||||||
<target name="init">
|
<target name="init">
|
||||||
<mkdir dir="${build}"/>
|
<mkdir dir="${build}"/>
|
||||||
@@ -36,24 +38,10 @@
|
|||||||
</depend>
|
</depend>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="dependServlet" if="depend.available">
|
<target name="compile" depends="init, depend, warUpToDate">
|
||||||
<depend
|
|
||||||
cache="../../build"
|
|
||||||
srcdir="${src}"
|
|
||||||
destdir="${build}" >
|
|
||||||
<!-- Depend on classes instead of jars where available -->
|
|
||||||
<classpath>
|
|
||||||
<pathelement location="../../core/java/build/obj" />
|
|
||||||
<pathelement location="../jetty/jettylib/javax.servlet.jar" />
|
|
||||||
</classpath>
|
|
||||||
</depend>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="compile" depends="init, depend">
|
|
||||||
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||||
includeAntRuntime="false"
|
includeAntRuntime="false"
|
||||||
srcdir="${src}" destdir="${build}"
|
srcdir="${src}" destdir="${build}">
|
||||||
excludes="net/i2p/addressbook/Servlet.java">
|
|
||||||
<compilerarg line="${javac.compilerargs}" />
|
<compilerarg line="${javac.compilerargs}" />
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="../../core/java/build/i2p.jar" />
|
<pathelement location="../../core/java/build/i2p.jar" />
|
||||||
@@ -61,55 +49,30 @@
|
|||||||
</javac>
|
</javac>
|
||||||
</target>
|
</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" />
|
|
||||||
<pathelement location="../jetty/jettylib/javax.servlet.jar" />
|
|
||||||
</classpath>
|
|
||||||
</javac>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<!-- unused for now (except for Android), as we oddly ship addressbook as a .war -->
|
|
||||||
<target name="jar" depends="compile, changes">
|
<target name="jar" depends="compile, changes">
|
||||||
<!-- set if unset -->
|
<!-- set if unset -->
|
||||||
<property name="workspace.changes" value="" />
|
<property name="workspace.changes.tr" value="" />
|
||||||
<jar basedir="${build}" destfile="${dist}/${jar}">
|
<jar basedir="${build}" destfile="${dist}/${jar}">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Main-Class" value="addressbook.Daemon"/>
|
<attribute name="Main-Class" value="net.i2p.addressbook.Daemon"/>
|
||||||
<attribute name="Implementation-Version" value="${full.version}" />
|
|
||||||
<attribute name="Built-By" value="${build.built-by}" />
|
|
||||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
|
||||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
|
||||||
<attribute name="Workspace-Changes" value="${workspace.changes}" />
|
|
||||||
</manifest>
|
|
||||||
</jar>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<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"/>
|
|
||||||
<copy todir="${dist}/tmp/WEB-INF/classes">
|
|
||||||
<fileset dir="${build}"/>
|
|
||||||
</copy>
|
|
||||||
<!-- set if unset -->
|
|
||||||
<property name="workspace.changes.tr" value="" />
|
|
||||||
<war basedir="${dist}/tmp" webxml="web.xml" destfile="${dist}/${war}">
|
|
||||||
<manifest>
|
|
||||||
<attribute name="Implementation-Version" value="${full.version}" />
|
<attribute name="Implementation-Version" value="${full.version}" />
|
||||||
<attribute name="Built-By" value="${build.built-by}" />
|
<attribute name="Built-By" value="${build.built-by}" />
|
||||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||||
|
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||||
|
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</war>
|
</jar>
|
||||||
<delete dir="${dist}/tmp"/>
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="emptyWar" depends="init">
|
||||||
|
<jar destfile="${dist}/${war}" >
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Note" value="Intentionally empty" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="warUpToDate">
|
<target name="warUpToDate">
|
||||||
<uptodate property="war.uptodate" targetfile="${dist}/${war}">
|
<uptodate property="war.uptodate" targetfile="${dist}/${war}">
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.client.naming.HostTxtEntry;
|
||||||
import net.i2p.util.EepGet;
|
import net.i2p.util.EepGet;
|
||||||
import net.i2p.util.SecureFile;
|
import net.i2p.util.SecureFile;
|
||||||
|
|
||||||
@@ -37,18 +39,40 @@ import net.i2p.util.SecureFile;
|
|||||||
* destinations. AddressBooks can be created from local and remote files, merged
|
* destinations. AddressBooks can be created from local and remote files, merged
|
||||||
* together, and written out to local files.
|
* together, and written out to local files.
|
||||||
*
|
*
|
||||||
|
* Methods are NOT thread-safe.
|
||||||
|
*
|
||||||
* @author Ragnarok
|
* @author Ragnarok
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class AddressBook {
|
class AddressBook implements Iterable<Map.Entry<String, HostTxtEntry>> {
|
||||||
|
|
||||||
private final String location;
|
private final String location;
|
||||||
/** either addresses or subFile will be non-null, but not both */
|
/** either addresses or subFile will be non-null, but not both */
|
||||||
private final Map<String, String> addresses;
|
private final Map<String, HostTxtEntry> addresses;
|
||||||
private final File subFile;
|
private final File subFile;
|
||||||
private boolean modified;
|
private boolean modified;
|
||||||
private static final boolean DEBUG = false;
|
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.
|
* Construct an AddressBook from the contents of the Map addresses.
|
||||||
*
|
*
|
||||||
@@ -56,7 +80,7 @@ class AddressBook {
|
|||||||
* A Map containing human readable addresses as keys, mapped to
|
* A Map containing human readable addresses as keys, mapped to
|
||||||
* base64 i2p destinations.
|
* base64 i2p destinations.
|
||||||
*/
|
*/
|
||||||
public AddressBook(Map<String, String> addresses) {
|
public AddressBook(Map<String, HostTxtEntry> addresses) {
|
||||||
this.addresses = addresses;
|
this.addresses = addresses;
|
||||||
this.subFile = null;
|
this.subFile = null;
|
||||||
this.location = null;
|
this.location = null;
|
||||||
@@ -86,7 +110,7 @@ class AddressBook {
|
|||||||
new File("addressbook.tmp").delete();
|
new File("addressbook.tmp").delete();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
static final long MAX_SUB_SIZE = 3 * 1024 * 1024l; //about 5,000 hosts
|
static final long MAX_SUB_SIZE = 5 * 1024 * 1024l; //about 8,000 hosts
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an AddressBook from the Subscription subscription. If the
|
* Construct an AddressBook from the Subscription subscription. If the
|
||||||
@@ -107,7 +131,7 @@ class AddressBook {
|
|||||||
* @param proxyPort port number of proxy
|
* @param proxyPort port number of proxy
|
||||||
*/
|
*/
|
||||||
public AddressBook(Subscription subscription, String proxyHost, int proxyPort) {
|
public AddressBook(Subscription subscription, String proxyHost, int proxyPort) {
|
||||||
Map<String, String> a = null;
|
Map<String, HostTxtEntry> a = null;
|
||||||
File subf = null;
|
File subf = null;
|
||||||
try {
|
try {
|
||||||
File tmp = SecureFile.createTempFile("addressbook", null, I2PAppContext.getGlobalContext().getTempDir());
|
File tmp = SecureFile.createTempFile("addressbook", null, I2PAppContext.getGlobalContext().getTempDir());
|
||||||
@@ -144,23 +168,40 @@ class AddressBook {
|
|||||||
*/
|
*/
|
||||||
public AddressBook(File file) {
|
public AddressBook(File file) {
|
||||||
this.location = file.toString();
|
this.location = file.toString();
|
||||||
Map<String, String> a;
|
Map<String, HostTxtEntry> a;
|
||||||
try {
|
try {
|
||||||
a = ConfigParser.parse(file);
|
a = HostTxtParser.parse(file);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {
|
||||||
a = new HashMap<String, String>();
|
a = new HashMap<String, HostTxtEntry>();
|
||||||
}
|
}
|
||||||
this.addresses = a;
|
this.addresses = a;
|
||||||
this.subFile = null;
|
this.subFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test only.
|
||||||
|
*
|
||||||
|
* @param testsubfile path to a file containing the simulated fetch of a subscription
|
||||||
|
* @since 0.9.26
|
||||||
|
*/
|
||||||
|
public AddressBook(String testsubfile) {
|
||||||
|
this.location = testsubfile;
|
||||||
|
this.addresses = null;
|
||||||
|
this.subFile = new File(testsubfile);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an iterator over the addresses in the AddressBook.
|
* Return an iterator over the addresses in the AddressBook.
|
||||||
* @since 0.8.7
|
* @since 0.8.7
|
||||||
*/
|
*/
|
||||||
public Iterator<Map.Entry<String, String>> iterator() {
|
public Iterator<Map.Entry<String, HostTxtEntry>> iterator() {
|
||||||
if (this.subFile != null)
|
if (this.subFile != null) {
|
||||||
return new ConfigIterator(this.subFile);
|
try {
|
||||||
|
return new HostTxtIterator(this.subFile);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
return new HostTxtIterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.addresses.entrySet().iterator();
|
return this.addresses.entrySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,12 +242,9 @@ class AddressBook {
|
|||||||
return "Map containing " + this.addresses.size() + " entries";
|
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
|
* Do basic validation of the hostname
|
||||||
* hostname was already converted to lower case by ConfigParser.parse()
|
* hostname was already converted to lower case by HostTxtParser.parse()
|
||||||
*/
|
*/
|
||||||
public static boolean isValidKey(String host) {
|
public static boolean isValidKey(String host) {
|
||||||
return
|
return
|
||||||
@@ -220,9 +258,10 @@ class AddressBook {
|
|||||||
host.indexOf("..") < 0 &&
|
host.indexOf("..") < 0 &&
|
||||||
// IDN - basic check, not complete validation
|
// IDN - basic check, not complete validation
|
||||||
(host.indexOf("--") < 0 || host.startsWith("xn--") || host.indexOf(".xn--") > 0) &&
|
(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)
|
// 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 ...
|
// ... or maybe we do Base32 this way ...
|
||||||
(! host.equals("b32.i2p")) &&
|
(! host.equals("b32.i2p")) &&
|
||||||
(! host.endsWith(".b32.i2p")) &&
|
(! host.endsWith(".b32.i2p")) &&
|
||||||
@@ -246,7 +285,7 @@ class AddressBook {
|
|||||||
(dest.length() > MIN_DEST_LENGTH && dest.length() <= MAX_DEST_LENGTH)) &&
|
(dest.length() > MIN_DEST_LENGTH && dest.length() <= MAX_DEST_LENGTH)) &&
|
||||||
// B64 comes in groups of 2, 3, or 4 chars, but never 1
|
// B64 comes in groups of 2, 3, or 4 chars, but never 1
|
||||||
((dest.length() % 4) != 1) &&
|
((dest.length() % 4) != 1) &&
|
||||||
dest.replaceAll("[a-zA-Z0-9~-]", "").length() == 0
|
B64_PATTERN.matcher(dest).matches()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,15 +306,15 @@ class AddressBook {
|
|||||||
public void merge(AddressBook other, boolean overwrite, Log log) {
|
public void merge(AddressBook other, boolean overwrite, Log log) {
|
||||||
if (this.addresses == null)
|
if (this.addresses == null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
for (Iterator<Map.Entry<String, String>> iter = other.iterator(); iter.hasNext(); ) {
|
for (Iterator<Map.Entry<String, HostTxtEntry>> iter = other.iterator(); iter.hasNext(); ) {
|
||||||
Map.Entry<String, String> entry = iter.next();
|
Map.Entry<String, HostTxtEntry> entry = iter.next();
|
||||||
String otherKey = entry.getKey();
|
String otherKey = entry.getKey();
|
||||||
String otherValue = entry.getValue();
|
HostTxtEntry otherValue = entry.getValue();
|
||||||
|
|
||||||
if (isValidKey(otherKey) && isValidDest(otherValue)) {
|
if (isValidKey(otherKey) && isValidDest(otherValue.getDest())) {
|
||||||
if (this.addresses.containsKey(otherKey) && !overwrite) {
|
if (this.addresses.containsKey(otherKey) && !overwrite) {
|
||||||
if (DEBUG && log != null &&
|
if (DEBUG && log != null &&
|
||||||
!this.addresses.get(otherKey).equals(otherValue)) {
|
!this.addresses.get(otherKey).equals(otherValue.getDest())) {
|
||||||
log.append("Conflict for " + otherKey + " from "
|
log.append("Conflict for " + otherKey + " from "
|
||||||
+ other.location
|
+ other.location
|
||||||
+ ". Destination in remote address book is "
|
+ ". Destination in remote address book is "
|
||||||
@@ -308,7 +347,7 @@ class AddressBook {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
if (this.modified) {
|
if (this.modified) {
|
||||||
try {
|
try {
|
||||||
ConfigParser.write(this.addresses, file);
|
HostTxtParser.write(this.addresses, file);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {
|
||||||
System.err.println("Error writing addressbook " + file.getAbsolutePath() + " : " + exp.toString());
|
System.err.println("Error writing addressbook " + file.getAbsolutePath() + " : " + exp.toString());
|
||||||
}
|
}
|
||||||
@@ -332,4 +371,27 @@ class AddressBook {
|
|||||||
protected void finalize() {
|
protected void finalize() {
|
||||||
delete();
|
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));
|
||||||
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,12 +29,13 @@ import java.io.IOException;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.util.SecureFile;
|
import net.i2p.util.SecureFile;
|
||||||
import net.i2p.util.SecureFileOutputStream;
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
import net.i2p.util.SystemVersion;
|
import net.i2p.util.SystemVersion;
|
||||||
@@ -43,8 +44,7 @@ import net.i2p.util.SystemVersion;
|
|||||||
* Utility class providing methods to parse and write files in config file
|
* Utility class providing methods to parse and write files in config file
|
||||||
* format, and subscription file format.
|
* format, and subscription file format.
|
||||||
*
|
*
|
||||||
* TODO: Change file encoding from default to UTF-8?
|
* TODO: switch to the DataHelper loadProps/storeProps methods?
|
||||||
* Or switch to the DataHelper loadProps/storeProps methods?
|
|
||||||
*
|
*
|
||||||
* @author Ragnarok
|
* @author Ragnarok
|
||||||
*/
|
*/
|
||||||
@@ -87,20 +87,23 @@ class ConfigParser {
|
|||||||
* if the BufferedReader cannot be read.
|
* if the BufferedReader cannot be read.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parse(BufferedReader input) throws IOException {
|
private static Map<String, String> parse(BufferedReader input) throws IOException {
|
||||||
Map<String, String> result = new HashMap<String, String>();
|
try {
|
||||||
String inputLine;
|
Map<String, String> result = new HashMap<String, String>();
|
||||||
inputLine = input.readLine();
|
String inputLine;
|
||||||
while (inputLine != null) {
|
while ((inputLine = input.readLine()) != null) {
|
||||||
inputLine = stripComments(inputLine);
|
inputLine = stripComments(inputLine);
|
||||||
String[] splitLine = inputLine.split("=");
|
if (inputLine.length() == 0)
|
||||||
if (splitLine.length == 2) {
|
continue;
|
||||||
result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
|
String[] splitLine = DataHelper.split(inputLine, "=", 2);
|
||||||
|
if (splitLine.length == 2) {
|
||||||
|
result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inputLine = input.readLine();
|
return result;
|
||||||
|
} finally {
|
||||||
|
try { input.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
input.close();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,15 +116,21 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if file cannot be read.
|
* if file cannot be read.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parse(File file) throws IOException {
|
public static Map<String, String> parse(File file) throws IOException {
|
||||||
FileInputStream fileStream = new FileInputStream(file);
|
FileInputStream fileStream = null;
|
||||||
BufferedReader input = new BufferedReader(new InputStreamReader(
|
|
||||||
fileStream));
|
|
||||||
Map<String, String> rv = parse(input);
|
|
||||||
try {
|
try {
|
||||||
fileStream.close();
|
fileStream = new FileInputStream(file);
|
||||||
} catch (IOException ioe) {}
|
BufferedReader input = new BufferedReader(new InputStreamReader(
|
||||||
return rv;
|
fileStream, "UTF-8"));
|
||||||
|
Map<String, String> rv = parse(input);
|
||||||
|
return rv;
|
||||||
|
} finally {
|
||||||
|
if (fileStream != null) {
|
||||||
|
try {
|
||||||
|
fileStream.close();
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,11 +143,13 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if file cannot be read.
|
* if file cannot be read.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parse(String string) throws IOException {
|
/****
|
||||||
|
public static Map<String, String> parse(String string) throws IOException {
|
||||||
StringReader stringReader = new StringReader(string);
|
StringReader stringReader = new StringReader(string);
|
||||||
BufferedReader input = new BufferedReader(stringReader);
|
BufferedReader input = new BufferedReader(stringReader);
|
||||||
return parse(input);
|
return parse(input);
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a Map using the contents of the File file. If file cannot be read,
|
* Return a Map using the contents of the File file. If file cannot be read,
|
||||||
@@ -151,8 +162,8 @@ class ConfigParser {
|
|||||||
* @return A Map containing the key, value pairs from file, or if file
|
* @return A Map containing the key, value pairs from file, or if file
|
||||||
* cannot be read, map.
|
* cannot be read, map.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parse(File file, Map<String, String> map) {
|
public static Map<String, String> parse(File file, Map<String, String> map) {
|
||||||
Map<String, String> result;
|
Map<String, String> result;
|
||||||
try {
|
try {
|
||||||
result = parse(file);
|
result = parse(file);
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
@@ -178,19 +189,21 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if input cannot be read.
|
* if input cannot be read.
|
||||||
*/
|
*/
|
||||||
public static List<String> parseSubscriptions(BufferedReader input)
|
private static List<String> parseSubscriptions(BufferedReader input)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
List<String> result = new LinkedList<String>();
|
try {
|
||||||
String inputLine = input.readLine();
|
List<String> result = new ArrayList<String>(4);
|
||||||
while (inputLine != null) {
|
String inputLine;
|
||||||
inputLine = stripComments(inputLine).trim();
|
while ((inputLine = input.readLine()) != null) {
|
||||||
if (inputLine.length() > 0) {
|
inputLine = stripComments(inputLine).trim();
|
||||||
result.add(inputLine);
|
if (inputLine.length() > 0) {
|
||||||
|
result.add(inputLine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inputLine = input.readLine();
|
return result;
|
||||||
|
} finally {
|
||||||
|
try { input.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
input.close();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,15 +215,21 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if file cannot be read.
|
* if file cannot be read.
|
||||||
*/
|
*/
|
||||||
public static List<String> parseSubscriptions(File file) throws IOException {
|
private static List<String> parseSubscriptions(File file) throws IOException {
|
||||||
FileInputStream fileStream = new FileInputStream(file);
|
FileInputStream fileStream = null;
|
||||||
BufferedReader input = new BufferedReader(new InputStreamReader(
|
|
||||||
fileStream));
|
|
||||||
List<String> rv = parseSubscriptions(input);
|
|
||||||
try {
|
try {
|
||||||
fileStream.close();
|
fileStream = new FileInputStream(file);
|
||||||
} catch (IOException ioe) {}
|
BufferedReader input = new BufferedReader(new InputStreamReader(
|
||||||
return rv;
|
fileStream, "UTF-8"));
|
||||||
|
List<String> rv = parseSubscriptions(input);
|
||||||
|
return rv;
|
||||||
|
} finally {
|
||||||
|
if (fileStream != null) {
|
||||||
|
try {
|
||||||
|
fileStream.close();
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,11 +241,13 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if string cannot be read.
|
* if string cannot be read.
|
||||||
*/
|
*/
|
||||||
|
/****
|
||||||
public static List<String> parseSubscriptions(String string) throws IOException {
|
public static List<String> parseSubscriptions(String string) throws IOException {
|
||||||
StringReader stringReader = new StringReader(string);
|
StringReader stringReader = new StringReader(string);
|
||||||
BufferedReader input = new BufferedReader(stringReader);
|
BufferedReader input = new BufferedReader(stringReader);
|
||||||
return parseSubscriptions(input);
|
return parseSubscriptions(input);
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a List using the contents of the File file. If file cannot be
|
* Return a List using the contents of the File file. If file cannot be
|
||||||
@@ -276,12 +297,15 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if the BufferedWriter cannot be written to.
|
* if the BufferedWriter cannot be written to.
|
||||||
*/
|
*/
|
||||||
public static void write(Map<String, String> map, BufferedWriter output) throws IOException {
|
private static void write(Map<String, String> map, BufferedWriter output) throws IOException {
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
try {
|
||||||
output.write(entry.getKey() + '=' + entry.getValue());
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
output.newLine();
|
output.write(entry.getKey() + '=' + entry.getValue());
|
||||||
|
output.newLine();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try { output.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
output.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,7 +322,7 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if file cannot be written to.
|
* if file cannot be written to.
|
||||||
*/
|
*/
|
||||||
public static void write(Map<String, String> map, File file) throws IOException {
|
public static void write(Map<String, String> map, File file) throws IOException {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
if (!isWindows) {
|
if (!isWindows) {
|
||||||
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
|
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
|
||||||
@@ -326,13 +350,16 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if output cannot be written to.
|
* if output cannot be written to.
|
||||||
*/
|
*/
|
||||||
public static void writeSubscriptions(List<String> list, BufferedWriter output)
|
private static void writeSubscriptions(List<String> list, BufferedWriter output)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
for (String s : list) {
|
try {
|
||||||
output.write(s);
|
for (String s : list) {
|
||||||
output.newLine();
|
output.write(s);
|
||||||
|
output.newLine();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try { output.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
output.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,7 +373,7 @@ class ConfigParser {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if output cannot be written to.
|
* if output cannot be written to.
|
||||||
*/
|
*/
|
||||||
public static void writeSubscriptions(List<String> list, File file)
|
private static void writeSubscriptions(List<String> list, File file)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
writeSubscriptions(list, new BufferedWriter(
|
writeSubscriptions(list, new BufferedWriter(
|
||||||
new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
||||||
|
|||||||
@@ -23,36 +23,45 @@ package net.i2p.addressbook;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.client.naming.HostTxtEntry;
|
||||||
import net.i2p.client.naming.NamingService;
|
import net.i2p.client.naming.NamingService;
|
||||||
import net.i2p.client.naming.SingleFileNamingService;
|
import net.i2p.client.naming.SingleFileNamingService;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.util.OrderedProperties;
|
||||||
import net.i2p.util.SecureDirectory;
|
import net.i2p.util.SecureDirectory;
|
||||||
import net.i2p.util.SystemVersion;
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class of addressbook. Performs updates, and runs the main loop.
|
* Main class of addressbook. Performs updates, and runs the main loop.
|
||||||
|
* As of 0.9.30, package private, run with DaemonThread.
|
||||||
*
|
*
|
||||||
* @author Ragnarok
|
* @author Ragnarok
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Daemon {
|
class Daemon {
|
||||||
public static final String VERSION = "2.0.4";
|
public static final String VERSION = "2.0.4";
|
||||||
private static final Daemon _instance = new Daemon();
|
|
||||||
private volatile boolean _running;
|
private volatile boolean _running;
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
// If you change this, change in SusiDNS SubscriptionBean also
|
||||||
private static final String DEFAULT_SUB = "http://i2p-projekt.i2p/hosts.txt";
|
private static final String DEFAULT_SUB = "http://i2p-projekt.i2p/hosts.txt";
|
||||||
/** @since 0.9.12 */
|
/** @since 0.9.12 */
|
||||||
static final String OLD_DEFAULT_SUB = "http://www.i2p2.i2p/hosts.txt";
|
static final String OLD_DEFAULT_SUB = "http://www.i2p2.i2p/hosts.txt";
|
||||||
|
/** Any properties we receive from the subscription, we store to the
|
||||||
|
* addressbook with this prefix, so it knows it's part of the signature.
|
||||||
|
* This is also chosen so that it can't be spoofed.
|
||||||
|
*/
|
||||||
|
private static final String RCVD_PROP_PREFIX = "=";
|
||||||
|
private static final boolean MUST_VALIDATE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the router and published address books using remote data from the
|
* Update the router and published address books using remote data from the
|
||||||
@@ -80,10 +89,9 @@ public class Daemon {
|
|||||||
*/
|
*/
|
||||||
public static void update(AddressBook master, AddressBook router,
|
public static void update(AddressBook master, AddressBook router,
|
||||||
File published, SubscriptionList subscriptions, Log log) {
|
File published, SubscriptionList subscriptions, Log log) {
|
||||||
Iterator<AddressBook> iter = subscriptions.iterator();
|
for (AddressBook book : subscriptions) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
// yes, the EepGet fetch() is done in next()
|
// yes, the EepGet fetch() is done in next()
|
||||||
router.merge(iter.next(), false, log);
|
router.merge(book, false, log);
|
||||||
}
|
}
|
||||||
router.write();
|
router.write();
|
||||||
if (published != null) {
|
if (published != null) {
|
||||||
@@ -129,18 +137,22 @@ public class Daemon {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
// yes, the EepGet fetch() is done in next()
|
// yes, the EepGet fetch() is done in next()
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
AddressBook sub = iter.next();
|
AddressBook addressbook = iter.next();
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
// SubscriptionIterator puts in a dummy AddressBook with no location if no fetch is done
|
// SubscriptionIterator puts in a dummy AddressBook with no location if no fetch is done
|
||||||
if (DEBUG && log != null && sub.getLocation() != null)
|
if (DEBUG && log != null && addressbook.getLocation() != null) {
|
||||||
log.append("Fetch of " + sub.getLocation() + " took " + (end - start));
|
long end = System.currentTimeMillis();
|
||||||
start = end;
|
log.append("Fetch of " + addressbook.getLocation() + " took " + (end - start));
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
int old = 0, nnew = 0, invalid = 0, conflict = 0, total = 0;
|
int old = 0, nnew = 0, invalid = 0, conflict = 0, total = 0;
|
||||||
for (Iterator<Map.Entry<String, String>> eIter = sub.iterator(); eIter.hasNext(); ) {
|
int deleted = 0;
|
||||||
Map.Entry<String, String> entry = eIter.next();
|
for (Map.Entry<String, HostTxtEntry> entry : addressbook) {
|
||||||
|
total++;
|
||||||
|
// may be null for 'remove' entries
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
boolean isKnown;
|
boolean isKnown;
|
||||||
Destination oldDest = null;
|
// NOT set for text file NamingService
|
||||||
|
Destination oldDest;
|
||||||
if (isTextFile) {
|
if (isTextFile) {
|
||||||
if (knownNames == null) {
|
if (knownNames == null) {
|
||||||
// load the hostname set
|
// load the hostname set
|
||||||
@@ -148,22 +160,305 @@ public class Daemon {
|
|||||||
opts.setProperty("file", "hosts.txt");
|
opts.setProperty("file", "hosts.txt");
|
||||||
knownNames = router.getNames(opts);
|
knownNames = router.getNames(opts);
|
||||||
}
|
}
|
||||||
isKnown = knownNames.contains(key);
|
oldDest = null;
|
||||||
|
isKnown = key != null ? knownNames.contains(key) : null;
|
||||||
} else {
|
} else {
|
||||||
oldDest = router.lookup(key);
|
oldDest = key != null ? router.lookup(key) : null;
|
||||||
isKnown = oldDest != null;
|
isKnown = oldDest != null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!isKnown) {
|
HostTxtEntry he = entry.getValue();
|
||||||
if (AddressBook.isValidKey(key)) {
|
Properties hprops = he.getProps();
|
||||||
Destination dest = new Destination(entry.getValue());
|
boolean mustValidate = MUST_VALIDATE || hprops != null;
|
||||||
Properties props = new Properties();
|
String action = hprops != null ? hprops.getProperty(HostTxtEntry.PROP_ACTION) : null;
|
||||||
props.setProperty("s", sub.getLocation());
|
if (key == null && !he.hasValidRemoveSig()) {
|
||||||
|
if (log != null) {
|
||||||
|
log.append("Bad signature of action " + action + " for key " +
|
||||||
|
hprops.getProperty(HostTxtEntry.PROP_NAME) +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
invalid++;
|
||||||
|
} else if (key != null && mustValidate && !he.hasValidSig()) {
|
||||||
|
if (log != null) {
|
||||||
|
log.append("Bad signature of action " + action + " for key " + key +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
invalid++;
|
||||||
|
} else if (action != null || !isKnown) {
|
||||||
|
if (key != null && AddressBook.isValidKey(key)) {
|
||||||
|
Destination dest = new Destination(he.getDest());
|
||||||
|
Properties props = new OrderedProperties();
|
||||||
|
props.setProperty("s", addressbook.getLocation());
|
||||||
|
boolean allowExistingKeyInPublished = false;
|
||||||
|
if (mustValidate) {
|
||||||
|
// sig checked above
|
||||||
|
props.setProperty("v", "true");
|
||||||
|
}
|
||||||
|
if (hprops != null) {
|
||||||
|
// merge in all the received properties
|
||||||
|
for (Map.Entry<Object, Object> e : hprops.entrySet()) {
|
||||||
|
// Add prefix to indicate received property
|
||||||
|
props.setProperty(RCVD_PROP_PREFIX + e.getKey(), (String) e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action != null) {
|
||||||
|
// Process commands. hprops is non-null.
|
||||||
|
// Must handle isKnown in each case.
|
||||||
|
if (action.equals(HostTxtEntry.ACTION_ADDDEST)) {
|
||||||
|
// Add an alternate destination (new crypto) for existing hostname
|
||||||
|
// Requires new NamingService support if the key exists
|
||||||
|
String polddest = hprops.getProperty(HostTxtEntry.PROP_OLDDEST);
|
||||||
|
if (polddest != null) {
|
||||||
|
Destination pod = new Destination(polddest);
|
||||||
|
List<Destination> pod2 = router.lookupAll(key);
|
||||||
|
if (pod2 == null) {
|
||||||
|
// we didn't know it before, so we'll add it
|
||||||
|
// check inner sig anyway
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (pod2.contains(dest)) {
|
||||||
|
// we knew it before, with the same dest
|
||||||
|
old++;
|
||||||
|
continue;
|
||||||
|
} else if (pod2.contains(pod)) {
|
||||||
|
// checks out, so verify the inner sig
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO Requires NamingService support
|
||||||
|
// if (isTextFile), do we replace or not? check sigType.isAvailable()
|
||||||
|
boolean success = router.addDestination(key, dest, props);
|
||||||
|
if (log != null) {
|
||||||
|
if (success)
|
||||||
|
log.append("Additional address for " + key +
|
||||||
|
" added to address book. From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Failed to add additional address for " + key +
|
||||||
|
" From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
// now update the published addressbook
|
||||||
|
// ditto
|
||||||
|
if (published != null) {
|
||||||
|
if (publishedNS == null)
|
||||||
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
|
// FIXME this fails, no support in SFNS
|
||||||
|
success = publishedNS.addDestination(key, dest, props);
|
||||||
|
if (log != null && !success)
|
||||||
|
log.append("Add to published address book " + published.getAbsolutePath() + " failed for " + key);
|
||||||
|
}
|
||||||
|
nnew++;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod2, he.getDest(), addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_ADDNAME)) {
|
||||||
|
// Add an alias for an existing hostname, same dest
|
||||||
|
if (isKnown) {
|
||||||
|
// could be same or different dest
|
||||||
|
old++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String poldname = hprops.getProperty(HostTxtEntry.PROP_OLDNAME);
|
||||||
|
if (poldname != null) {
|
||||||
|
List<Destination> pod = router.lookupAll(poldname);
|
||||||
|
if (pod == null) {
|
||||||
|
// we didn't have the old one, so we'll add the new one
|
||||||
|
} else if (pod.contains(dest)) {
|
||||||
|
// checks out, so we'll add the new one
|
||||||
|
} else {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod, he.getDest(), addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_ADDSUBDOMAIN)) {
|
||||||
|
// add a subdomain with verification
|
||||||
|
if (isKnown) {
|
||||||
|
old++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String polddest = hprops.getProperty(HostTxtEntry.PROP_OLDDEST);
|
||||||
|
String poldname = hprops.getProperty(HostTxtEntry.PROP_OLDNAME);
|
||||||
|
if (polddest != null && poldname != null) {
|
||||||
|
// check for valid subdomain
|
||||||
|
if (!AddressBook.isValidKey(poldname) ||
|
||||||
|
key.indexOf('.' + poldname) <= 0) {
|
||||||
|
if (log != null)
|
||||||
|
log.append("Action: " + action + " failed because" +
|
||||||
|
" old name " + poldname +
|
||||||
|
" is invalid" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Destination pod = new Destination(polddest);
|
||||||
|
List<Destination> pod2 = router.lookupAll(poldname);
|
||||||
|
if (pod2 == null) {
|
||||||
|
// we didn't have the old name
|
||||||
|
// check inner sig anyway
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (pod2.contains(pod)) {
|
||||||
|
// checks out, so verify the inner sig
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod2, polddest, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_CHANGEDEST)) {
|
||||||
|
// change destination on an existing entry
|
||||||
|
// This removes all previous destinations under that hostname,
|
||||||
|
// is this what we want?
|
||||||
|
String polddest = hprops.getProperty(HostTxtEntry.PROP_OLDDEST);
|
||||||
|
if (polddest != null) {
|
||||||
|
Destination pod = new Destination(polddest);
|
||||||
|
List<Destination> pod2 = router.lookupAll(key);
|
||||||
|
if (pod2 == null) {
|
||||||
|
// we didn't have the old name
|
||||||
|
// check inner sig anyway
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (pod2.contains(dest)) {
|
||||||
|
// we already have the new dest
|
||||||
|
old++;
|
||||||
|
continue;
|
||||||
|
} else if (pod2.contains(pod)) {
|
||||||
|
// checks out, so verify the inner sig
|
||||||
|
if (!he.hasValidInnerSig()) {
|
||||||
|
logInner(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (log != null) {
|
||||||
|
if (pod2.size() == 1)
|
||||||
|
log.append("Changing destination for " + key +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Replacing " + pod2.size() + " destinations for " + key +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
allowExistingKeyInPublished = true;
|
||||||
|
props.setProperty("m", Long.toString(I2PAppContext.getGlobalContext().clock().now()));
|
||||||
|
} else {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod2, polddest, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_CHANGENAME)) {
|
||||||
|
// Delete old name, replace with new
|
||||||
|
// This removes all previous destinations under that hostname,
|
||||||
|
// is this what we want?
|
||||||
|
if (isKnown) {
|
||||||
|
old++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String poldname = hprops.getProperty(HostTxtEntry.PROP_OLDNAME);
|
||||||
|
if (poldname != null) {
|
||||||
|
List<Destination> pod = router.lookupAll(poldname);
|
||||||
|
if (pod == null) {
|
||||||
|
// we didn't have the old name
|
||||||
|
} else if (pod.contains(dest)) {
|
||||||
|
// checks out, so we'll delete it
|
||||||
|
if (knownNames != null)
|
||||||
|
knownNames.remove(poldname);
|
||||||
|
boolean success = router.remove(poldname, dest);
|
||||||
|
if (success)
|
||||||
|
deleted++;
|
||||||
|
if (log != null) {
|
||||||
|
if (success)
|
||||||
|
log.append("Removed: " + poldname +
|
||||||
|
" to be replaced with " + key +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Remove failed for: " + poldname +
|
||||||
|
" to be replaced with " + key +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
// now update the published addressbook
|
||||||
|
if (published != null) {
|
||||||
|
if (publishedNS == null)
|
||||||
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
|
success = publishedNS.remove(poldname, dest);
|
||||||
|
if (log != null && !success)
|
||||||
|
log.append("Remove from published address book " + published.getAbsolutePath() + " failed for " + poldname);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod, he.getDest(), addressbook);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, key, addressbook);
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_REMOVE) ||
|
||||||
|
action.equals(HostTxtEntry.ACTION_REMOVEALL)) {
|
||||||
|
// w/o name=dest handled below
|
||||||
|
if (log != null)
|
||||||
|
log.append("Action: " + action + " with name=dest invalid" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_UPDATE)) {
|
||||||
|
if (isKnown) {
|
||||||
|
allowExistingKeyInPublished = true;
|
||||||
|
props.setProperty("m", Long.toString(I2PAppContext.getGlobalContext().clock().now()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (log != null)
|
||||||
|
log.append("Action: " + action + " unrecognized" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} // action != null
|
||||||
boolean success = router.put(key, dest, props);
|
boolean success = router.put(key, dest, props);
|
||||||
if (log != null) {
|
if (log != null) {
|
||||||
if (success)
|
if (success)
|
||||||
log.append("New address " + key +
|
log.append("New address " + key +
|
||||||
" added to address book. From: " + sub.getLocation());
|
" added to address book. From: " + addressbook.getLocation());
|
||||||
else
|
else
|
||||||
log.append("Save to naming service " + router + " failed for new key " + key);
|
log.append("Save to naming service " + router + " failed for new key " + key);
|
||||||
}
|
}
|
||||||
@@ -171,59 +466,236 @@ public class Daemon {
|
|||||||
if (published != null) {
|
if (published != null) {
|
||||||
if (publishedNS == null)
|
if (publishedNS == null)
|
||||||
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
success = publishedNS.putIfAbsent(key, dest);
|
if (allowExistingKeyInPublished)
|
||||||
|
success = publishedNS.put(key, dest, props);
|
||||||
|
else
|
||||||
|
success = publishedNS.putIfAbsent(key, dest, props);
|
||||||
if (log != null && !success) {
|
if (log != null && !success) {
|
||||||
try {
|
log.append("Save to published address book " + published.getAbsolutePath() + " failed for new key " + key);
|
||||||
log.append("Save to published address book " + published.getCanonicalPath() + " failed for new key " + key);
|
|
||||||
} catch (IOException ioe) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isTextFile)
|
if (isTextFile)
|
||||||
// keep track for later dup check
|
// keep track for later dup check
|
||||||
knownNames.add(key);
|
knownNames.add(key);
|
||||||
nnew++;
|
nnew++;
|
||||||
|
} else if (key == null) {
|
||||||
|
// 'remove' actions
|
||||||
|
// isKnown is false
|
||||||
|
if (action != null) {
|
||||||
|
// Process commands. hprops is non-null.
|
||||||
|
if (action.equals(HostTxtEntry.ACTION_REMOVE)) {
|
||||||
|
// delete this entry
|
||||||
|
String polddest = hprops.getProperty(HostTxtEntry.PROP_DEST);
|
||||||
|
String poldname = hprops.getProperty(HostTxtEntry.PROP_NAME);
|
||||||
|
if (polddest != null && poldname != null) {
|
||||||
|
Destination pod = new Destination(polddest);
|
||||||
|
List<Destination> pod2 = router.lookupAll(poldname);
|
||||||
|
if (pod2 != null && pod2.contains(pod)) {
|
||||||
|
if (knownNames != null && pod2.size() == 1)
|
||||||
|
knownNames.remove(poldname);
|
||||||
|
boolean success = router.remove(poldname, pod);
|
||||||
|
if (success)
|
||||||
|
deleted++;
|
||||||
|
if (log != null) {
|
||||||
|
if (success)
|
||||||
|
log.append("Removed: " + poldname +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Remove failed for: " + poldname +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
// now update the published addressbook
|
||||||
|
if (published != null) {
|
||||||
|
if (publishedNS == null)
|
||||||
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
|
success = publishedNS.remove(poldname, pod);
|
||||||
|
if (log != null && !success)
|
||||||
|
log.append("Remove from published address book " + published.getAbsolutePath() + " failed for " + poldname);
|
||||||
|
}
|
||||||
|
} else if (pod2 != null) {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod2, polddest, addressbook);
|
||||||
|
invalid++;
|
||||||
|
} else {
|
||||||
|
old++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, "delete", addressbook);
|
||||||
|
invalid++;
|
||||||
|
}
|
||||||
|
} else if (action.equals(HostTxtEntry.ACTION_REMOVEALL)) {
|
||||||
|
// delete all entries with this destination
|
||||||
|
String polddest = hprops.getProperty(HostTxtEntry.PROP_DEST);
|
||||||
|
// oldname is optional, but nice because not all books support reverse lookup
|
||||||
|
if (polddest != null) {
|
||||||
|
Destination pod = new Destination(polddest);
|
||||||
|
String poldname = hprops.getProperty(HostTxtEntry.PROP_NAME);
|
||||||
|
if (poldname != null) {
|
||||||
|
List<Destination> pod2 = router.lookupAll(poldname);
|
||||||
|
if (pod2 != null && pod2.contains(pod)) {
|
||||||
|
if (knownNames != null)
|
||||||
|
knownNames.remove(poldname);
|
||||||
|
boolean success = router.remove(poldname, pod);
|
||||||
|
if (success)
|
||||||
|
deleted++;
|
||||||
|
if (log != null) {
|
||||||
|
if (success)
|
||||||
|
log.append("Removed: " + poldname +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Remove failed for: " + poldname +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
// now update the published addressbook
|
||||||
|
if (published != null) {
|
||||||
|
if (publishedNS == null)
|
||||||
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
|
success = publishedNS.remove(poldname, pod);
|
||||||
|
if (log != null && !success)
|
||||||
|
log.append("Remove from published address book " + published.getAbsolutePath() + " failed for " + poldname);
|
||||||
|
}
|
||||||
|
} else if (pod2 != null) {
|
||||||
|
// mismatch, disallow
|
||||||
|
logMismatch(log, action, key, pod2, polddest, addressbook);
|
||||||
|
invalid++;
|
||||||
|
} else {
|
||||||
|
old++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reverse lookup, delete all
|
||||||
|
List<String> revs = router.reverseLookupAll(pod);
|
||||||
|
if (revs != null) {
|
||||||
|
for (String rev : revs) {
|
||||||
|
if (knownNames != null)
|
||||||
|
knownNames.remove(rev);
|
||||||
|
boolean success = router.remove(rev, pod);
|
||||||
|
if (success)
|
||||||
|
deleted++;
|
||||||
|
if (log != null) {
|
||||||
|
if (success)
|
||||||
|
log.append("Removed: " + rev +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
else
|
||||||
|
log.append("Remove failed for: " + rev +
|
||||||
|
" as requested" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
// now update the published addressbook
|
||||||
|
if (published != null) {
|
||||||
|
if (publishedNS == null)
|
||||||
|
publishedNS = new SingleFileNamingService(I2PAppContext.getGlobalContext(), published.getAbsolutePath());
|
||||||
|
success = publishedNS.remove(rev, pod);
|
||||||
|
if (log != null && !success)
|
||||||
|
log.append("Remove from published address book " + published.getAbsolutePath() + " failed for " + rev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logMissing(log, action, "delete", addressbook);
|
||||||
|
invalid++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (log != null)
|
||||||
|
log.append("Action: " + action + " w/o name=dest unrecognized" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
invalid++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (log != null)
|
||||||
|
log.append("No action in command line" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
invalid++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else if (log != null) {
|
} else if (log != null) {
|
||||||
log.append("Bad hostname " + key + " from "
|
log.append("Bad hostname " + key + ". From: "
|
||||||
+ sub.getLocation());
|
+ addressbook.getLocation());
|
||||||
invalid++;
|
invalid++;
|
||||||
}
|
}
|
||||||
|
/****
|
||||||
} else if (false && DEBUG && log != null) {
|
} else if (false && DEBUG && log != null) {
|
||||||
// lookup the conflict if we haven't yet (O(n**2) for text file)
|
// lookup the conflict if we haven't yet (O(n**2) for text file)
|
||||||
if (isTextFile)
|
if (isTextFile)
|
||||||
oldDest = router.lookup(key);
|
oldDest = router.lookup(key);
|
||||||
if (oldDest != null && !oldDest.toBase64().equals(entry.getValue())) {
|
if (oldDest != null && !oldDest.toBase64().equals(entry.getValue())) {
|
||||||
log.append("Conflict for " + key + " from "
|
log.append("Conflict for " + key + ". From: "
|
||||||
+ sub.getLocation()
|
+ addressbook.getLocation()
|
||||||
+ ". Destination in remote address book is "
|
+ ". Destination in remote address book is "
|
||||||
+ entry.getValue());
|
+ entry.getValue());
|
||||||
conflict++;
|
conflict++;
|
||||||
} else {
|
} else {
|
||||||
old++;
|
old++;
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
} else {
|
} else {
|
||||||
old++;
|
old++;
|
||||||
}
|
}
|
||||||
} catch (DataFormatException dfe) {
|
} catch (DataFormatException dfe) {
|
||||||
if (log != null)
|
if (log != null)
|
||||||
log.append("Invalid b64 for " + key + " From: " + sub.getLocation());
|
log.append("Invalid b64 for " + key + " From: " + addressbook.getLocation());
|
||||||
invalid++;
|
invalid++;
|
||||||
}
|
}
|
||||||
total++;
|
|
||||||
}
|
}
|
||||||
if (DEBUG && log != null && total > 0) {
|
if (DEBUG && log != null && total > 0) {
|
||||||
log.append("Merge of " + sub.getLocation() + " into " + router +
|
log.append("Merge of " + addressbook.getLocation() + " into " + router +
|
||||||
" took " + (System.currentTimeMillis() - start) + " ms with " +
|
" took " + (System.currentTimeMillis() - start) + " ms with " +
|
||||||
total + " total, " +
|
total + " total, " +
|
||||||
nnew + " new, " +
|
nnew + " new, " +
|
||||||
old + " old, " +
|
old + " old, " +
|
||||||
|
deleted + " deleted, " +
|
||||||
invalid + " invalid, " +
|
invalid + " invalid, " +
|
||||||
conflict + " conflicts");
|
conflict + " conflicts");
|
||||||
}
|
} // entries
|
||||||
sub.delete();
|
addressbook.delete();
|
||||||
}
|
} // subscriptions
|
||||||
subscriptions.write();
|
subscriptions.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.26 */
|
||||||
|
private static void logInner(Log log, String action, String name, AddressBook addressbook) {
|
||||||
|
if (log != null) {
|
||||||
|
log.append("Action: " + action + " failed because" +
|
||||||
|
" inner signature for key " + name +
|
||||||
|
" failed" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.26 */
|
||||||
|
private static void logMissing(Log log, String action, String name, AddressBook addressbook) {
|
||||||
|
if (log != null) {
|
||||||
|
log.append("Action: " + action + " for " + name +
|
||||||
|
" failed, missing required parameters" +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.26 */
|
||||||
|
private static void logMismatch(Log log, String action, String name, List<Destination> dests,
|
||||||
|
String olddest, AddressBook addressbook) {
|
||||||
|
if (log != null) {
|
||||||
|
StringBuilder buf = new StringBuilder(16);
|
||||||
|
final int sz = dests.size();
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
buf.append(dests.get(i).toBase64().substring(0, 6));
|
||||||
|
if (i != sz - 1)
|
||||||
|
buf.append(", ");
|
||||||
|
}
|
||||||
|
log.append("Action: " + action + " failed because" +
|
||||||
|
" destinations for " + name +
|
||||||
|
" (" + buf + ')' +
|
||||||
|
" do not include" +
|
||||||
|
" (" + olddest.substring(0, 6) + ')' +
|
||||||
|
". From: " + addressbook.getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run an update, using the Map settings to provide the parameters.
|
* Run an update, using the Map settings to provide the parameters.
|
||||||
*
|
*
|
||||||
@@ -236,16 +708,12 @@ public class Daemon {
|
|||||||
File published = null;
|
File published = null;
|
||||||
boolean should_publish = Boolean.parseBoolean(settings.get("should_publish"));
|
boolean should_publish = Boolean.parseBoolean(settings.get("should_publish"));
|
||||||
if (should_publish)
|
if (should_publish)
|
||||||
published = new File(home, settings
|
published = new File(home, settings.get("published_addressbook"));
|
||||||
.get("published_addressbook"));
|
File subscriptionFile = new File(home, settings.get("subscriptions"));
|
||||||
File subscriptionFile = new File(home, settings
|
|
||||||
.get("subscriptions"));
|
|
||||||
File logFile = new File(home, settings.get("log"));
|
File logFile = new File(home, settings.get("log"));
|
||||||
File etagsFile = new File(home, settings.get("etags"));
|
File etagsFile = new File(home, settings.get("etags"));
|
||||||
File lastModifiedFile = new File(home, settings
|
File lastModifiedFile = new File(home, settings.get("last_modified"));
|
||||||
.get("last_modified"));
|
File lastFetchedFile = new File(home, settings.get("last_fetched"));
|
||||||
File lastFetchedFile = new File(home, settings
|
|
||||||
.get("last_fetched"));
|
|
||||||
long delay;
|
long delay;
|
||||||
try {
|
try {
|
||||||
delay = Long.parseLong(settings.get("update_delay"));
|
delay = Long.parseLong(settings.get("update_delay"));
|
||||||
@@ -254,13 +722,14 @@ public class Daemon {
|
|||||||
}
|
}
|
||||||
delay *= 60 * 60 * 1000;
|
delay *= 60 * 60 * 1000;
|
||||||
|
|
||||||
List<String> defaultSubs = new LinkedList<String>();
|
List<String> defaultSubs = new ArrayList<String>(4);
|
||||||
// defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
|
// defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
|
||||||
defaultSubs.add(DEFAULT_SUB);
|
defaultSubs.add(DEFAULT_SUB);
|
||||||
|
|
||||||
SubscriptionList subscriptions = new SubscriptionList(subscriptionFile,
|
SubscriptionList subscriptions = new SubscriptionList(subscriptionFile,
|
||||||
etagsFile, lastModifiedFile, lastFetchedFile, delay, defaultSubs, settings
|
etagsFile, lastModifiedFile, lastFetchedFile,
|
||||||
.get("proxy_host"), Integer.parseInt(settings.get("proxy_port")));
|
delay, defaultSubs, settings.get("proxy_host"),
|
||||||
|
Integer.parseInt(settings.get("proxy_port")));
|
||||||
Log log = SystemVersion.isAndroid() ? null : 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
|
// If false, add hosts via naming service; if true, write hosts.txt file directly
|
||||||
@@ -319,7 +788,25 @@ public class Daemon {
|
|||||||
* others are ignored.
|
* others are ignored.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
_instance.run(args);
|
Daemon daemon = new Daemon();
|
||||||
|
if (args != null && args.length > 0 && args[0].equals("test"))
|
||||||
|
daemon.test(args);
|
||||||
|
else
|
||||||
|
daemon.run(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.26 */
|
||||||
|
public static void test(String[] args) {
|
||||||
|
Properties ctxProps = new Properties();
|
||||||
|
String PROP_FORCE = "i2p.naming.blockfile.writeInAppContext";
|
||||||
|
ctxProps.setProperty(PROP_FORCE, "true");
|
||||||
|
I2PAppContext ctx = new I2PAppContext(ctxProps);
|
||||||
|
NamingService ns = getNamingService("hosts.txt");
|
||||||
|
File published = new File("test-published.txt");
|
||||||
|
Log log = new Log(new File("test-log.txt"));
|
||||||
|
SubscriptionList subscriptions = new SubscriptionList("test-sub.txt");
|
||||||
|
update(ns, published, subscriptions, log);
|
||||||
|
ctx.logManager().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(String[] args) {
|
public void run(String[] args) {
|
||||||
@@ -390,14 +877,14 @@ public class Daemon {
|
|||||||
* Call this to get the addressbook to reread its config and
|
* Call this to get the addressbook to reread its config and
|
||||||
* refetch its subscriptions.
|
* refetch its subscriptions.
|
||||||
*/
|
*/
|
||||||
public static void wakeup() {
|
public void wakeup() {
|
||||||
synchronized (_instance) {
|
synchronized (this) {
|
||||||
_instance.notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void stop() {
|
public void stop() {
|
||||||
_instance._running = false;
|
_running = false;
|
||||||
wakeup();
|
wakeup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.client.naming.NamingServiceUpdater;
|
import net.i2p.client.naming.NamingServiceUpdater;
|
||||||
|
import net.i2p.util.I2PAppThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A thread that waits five minutes, then runs the addressbook daemon.
|
* A thread that waits five minutes, then runs the addressbook daemon.
|
||||||
@@ -32,9 +33,10 @@ import net.i2p.client.naming.NamingServiceUpdater;
|
|||||||
* @author Ragnarok
|
* @author Ragnarok
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DaemonThread extends Thread implements NamingServiceUpdater {
|
public class DaemonThread extends I2PAppThread implements NamingServiceUpdater {
|
||||||
|
|
||||||
private String[] args;
|
private final String[] args;
|
||||||
|
private final Daemon daemon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a DaemonThread with the command line arguments args.
|
* Construct a DaemonThread with the command line arguments args.
|
||||||
@@ -43,6 +45,7 @@ public class DaemonThread extends Thread implements NamingServiceUpdater {
|
|||||||
*/
|
*/
|
||||||
public DaemonThread(String[] args) {
|
public DaemonThread(String[] args) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
daemon = new Daemon();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -55,18 +58,28 @@ public class DaemonThread extends Thread implements NamingServiceUpdater {
|
|||||||
//} catch (InterruptedException exp) {
|
//} catch (InterruptedException exp) {
|
||||||
//}
|
//}
|
||||||
I2PAppContext.getGlobalContext().namingService().registerUpdater(this);
|
I2PAppContext.getGlobalContext().namingService().registerUpdater(this);
|
||||||
Daemon.main(this.args);
|
try {
|
||||||
I2PAppContext.getGlobalContext().namingService().unregisterUpdater(this);
|
if (args != null && args.length > 0 && args[0].equals("test"))
|
||||||
|
daemon.test(args);
|
||||||
|
else
|
||||||
|
daemon.run(args);
|
||||||
|
} finally {
|
||||||
|
I2PAppContext.getGlobalContext().namingService().unregisterUpdater(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void halt() {
|
public void halt() {
|
||||||
Daemon.stop();
|
daemon.stop();
|
||||||
interrupt();
|
interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The NamingServiceUpdater interface
|
* The NamingServiceUpdater interface.
|
||||||
* @param options ignored
|
* While this may be called directly, the recommended way
|
||||||
|
* is to call I2PAppContext.namingService().requestUpdate(Properties)
|
||||||
|
* which will call this.
|
||||||
|
*
|
||||||
|
* @param options ignored, may be null
|
||||||
* @since 0.8.7
|
* @since 0.8.7
|
||||||
*/
|
*/
|
||||||
public void update(Properties options) {
|
public void update(Properties options) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
package net.i2p.addressbook;
|
package net.i2p.addressbook;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -31,6 +32,9 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import net.i2p.client.naming.HostTxtEntry;
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to iterate through a hosts.txt or config file without
|
* A class to iterate through a hosts.txt or config file without
|
||||||
* reading the whole thing into memory.
|
* reading the whole thing into memory.
|
||||||
@@ -39,26 +43,27 @@ import java.util.NoSuchElementException;
|
|||||||
* Callers should iterate all the way through or call close()
|
* Callers should iterate all the way through or call close()
|
||||||
* to ensure the underlying stream is closed.
|
* to ensure the underlying stream is closed.
|
||||||
*
|
*
|
||||||
* @since 0.8.7
|
* This is not used for config files.
|
||||||
|
* It is only used for subscriptions.
|
||||||
|
*
|
||||||
|
* @since 0.8.7, renamed from ConfigIterator in 0.9.26
|
||||||
*/
|
*/
|
||||||
class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
class HostTxtIterator implements Iterator<Map.Entry<String, HostTxtEntry>>, Closeable {
|
||||||
|
|
||||||
private BufferedReader input;
|
private BufferedReader input;
|
||||||
private ConfigEntry next;
|
private MapEntry next;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dummy iterator in which hasNext() is always false.
|
* A dummy iterator in which hasNext() is always false.
|
||||||
*/
|
*/
|
||||||
public ConfigIterator() {}
|
public HostTxtIterator() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An iterator over the key/value pairs in the file.
|
* An iterator over the key/value pairs in the file.
|
||||||
*/
|
*/
|
||||||
public ConfigIterator(File file) {
|
public HostTxtIterator(File file) throws IOException {
|
||||||
try {
|
|
||||||
FileInputStream fileStream = new FileInputStream(file);
|
FileInputStream fileStream = new FileInputStream(file);
|
||||||
input = new BufferedReader(new InputStreamReader(fileStream));
|
input = new BufferedReader(new InputStreamReader(fileStream, "UTF-8"));
|
||||||
} catch (IOException ioe) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
@@ -67,15 +72,13 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
|||||||
if (next != null)
|
if (next != null)
|
||||||
return true;
|
return true;
|
||||||
try {
|
try {
|
||||||
String inputLine = input.readLine();
|
String inputLine;
|
||||||
while (inputLine != null) {
|
while ((inputLine = input.readLine()) != null) {
|
||||||
inputLine = ConfigParser.stripComments(inputLine);
|
HostTxtEntry he = HostTxtParser.parse(inputLine, true);
|
||||||
String[] splitLine = inputLine.split("=");
|
if (he == null)
|
||||||
if (splitLine.length == 2) {
|
continue;
|
||||||
next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
|
next = new MapEntry(he.getName(), he);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
inputLine = input.readLine();
|
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {}
|
} catch (IOException ioe) {}
|
||||||
try { input.close(); } catch (IOException ioe) {}
|
try { input.close(); } catch (IOException ioe) {}
|
||||||
@@ -84,10 +87,15 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map.Entry<String, String> next() {
|
/**
|
||||||
|
* 'remove' entries will be returned with a null key,
|
||||||
|
* and the value will contain a null name, null dest,
|
||||||
|
* and non-null props.
|
||||||
|
*/
|
||||||
|
public Map.Entry<String, HostTxtEntry> next() {
|
||||||
if (!hasNext())
|
if (!hasNext())
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
Map.Entry<String, String> rv = next;
|
Map.Entry<String, HostTxtEntry> rv = next;
|
||||||
next = null;
|
next = null;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -110,11 +118,11 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
|||||||
/**
|
/**
|
||||||
* The object returned by the iterator.
|
* The object returned by the iterator.
|
||||||
*/
|
*/
|
||||||
private static class ConfigEntry implements Map.Entry<String, String> {
|
private static class MapEntry implements Map.Entry<String, HostTxtEntry> {
|
||||||
private final String key;
|
private final String key;
|
||||||
private final String value;
|
private final HostTxtEntry value;
|
||||||
|
|
||||||
public ConfigEntry(String k, String v) {
|
public MapEntry(String k, HostTxtEntry v) {
|
||||||
key = k;
|
key = k;
|
||||||
value = v;
|
value = v;
|
||||||
}
|
}
|
||||||
@@ -123,11 +131,11 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>> {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public HostTxtEntry getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String setValue(String v) {
|
public HostTxtEntry setValue(HostTxtEntry v) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
294
apps/addressbook/java/src/net/i2p/addressbook/HostTxtParser.java
Normal file
294
apps/addressbook/java/src/net/i2p/addressbook/HostTxtParser.java
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
package net.i2p.addressbook;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import net.i2p.client.naming.HostTxtEntry;
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
import net.i2p.util.SecureFile;
|
||||||
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class providing methods to parse and write files in a hosts.txt file
|
||||||
|
* format, and subscription file format.
|
||||||
|
*
|
||||||
|
* @since 0.9.26 modified from ConfigParser
|
||||||
|
*/
|
||||||
|
class HostTxtParser {
|
||||||
|
|
||||||
|
private static final boolean isWindows = SystemVersion.isWindows();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a Map using the contents of BufferedReader input. input must have
|
||||||
|
* a single key, value pair on each line, in the format: key=value. Lines
|
||||||
|
* starting with '#' or ';' are considered comments, and ignored. Lines that
|
||||||
|
* are obviously not in the format key=value are also ignored.
|
||||||
|
* The key is converted to lower case.
|
||||||
|
*
|
||||||
|
* Returned map will not contain null ("remove") entries.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* A BufferedReader with lines in key=value format to parse into
|
||||||
|
* a Map.
|
||||||
|
* @return A Map containing the key, value pairs from input.
|
||||||
|
* @throws IOException
|
||||||
|
* if the BufferedReader cannot be read.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static Map<String, HostTxtEntry> parse(BufferedReader input) throws IOException {
|
||||||
|
try {
|
||||||
|
Map<String, HostTxtEntry> result = new HashMap<String, HostTxtEntry>();
|
||||||
|
String inputLine;
|
||||||
|
while ((inputLine = input.readLine()) != null) {
|
||||||
|
HostTxtEntry he = parse(inputLine, false);
|
||||||
|
if (he == null)
|
||||||
|
continue;
|
||||||
|
result.put(he.getName(), he);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
try { input.close(); } catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a HostTxtEntry from the contents of the inputLine.
|
||||||
|
*
|
||||||
|
* @param inputLine key=value[#!k1=v1#k2=v2...]
|
||||||
|
* @param allowCommandOnly if true, a line starting with #! will return
|
||||||
|
* a HostTxtEntry with a null name and dest and non-null props.
|
||||||
|
* If false, these lines will return null.
|
||||||
|
* @return null if no entry found or on error
|
||||||
|
*/
|
||||||
|
public static HostTxtEntry parse(String inputLine, boolean allowCommandOnly) {
|
||||||
|
if (inputLine.startsWith(";"))
|
||||||
|
return null;
|
||||||
|
int comment = inputLine.indexOf('#');
|
||||||
|
String kv;
|
||||||
|
String sprops;
|
||||||
|
if (comment >= 0) {
|
||||||
|
int shebang = inputLine.indexOf(HostTxtEntry.PROPS_SEPARATOR);
|
||||||
|
if (shebang == comment && shebang + 2 < inputLine.length()) {
|
||||||
|
if (comment == 0 && !allowCommandOnly)
|
||||||
|
return null;
|
||||||
|
sprops = inputLine.substring(shebang + 2);
|
||||||
|
} else {
|
||||||
|
if (comment == 0)
|
||||||
|
return null;
|
||||||
|
sprops = null;
|
||||||
|
}
|
||||||
|
kv = inputLine.substring(0, comment);
|
||||||
|
} else {
|
||||||
|
sprops = null;
|
||||||
|
kv = inputLine;
|
||||||
|
}
|
||||||
|
String name, dest;
|
||||||
|
if (comment != 0) {
|
||||||
|
// we have a name=dest
|
||||||
|
String[] splitLine = DataHelper.split(kv, "=", 2);
|
||||||
|
if (splitLine.length < 2)
|
||||||
|
return null;
|
||||||
|
name = splitLine[0].trim().toLowerCase(Locale.US);
|
||||||
|
dest = splitLine[1].trim();
|
||||||
|
if (name.length() == 0 || dest.length() == 0)
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// line starts with #!, rv will contain props only
|
||||||
|
name = null;
|
||||||
|
dest = null;
|
||||||
|
}
|
||||||
|
HostTxtEntry he;
|
||||||
|
if (sprops != null) {
|
||||||
|
try {
|
||||||
|
he = new HostTxtEntry(name, dest, sprops);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
he = new HostTxtEntry(name, dest);
|
||||||
|
}
|
||||||
|
return he;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a Map using the contents of the File file. See parse(BufferedReader)
|
||||||
|
* for details of the input format.
|
||||||
|
*
|
||||||
|
* Returned map will not contain null ("remove") entries.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* A File to parse.
|
||||||
|
* @return A Map containing the key, value pairs from file.
|
||||||
|
* @throws IOException
|
||||||
|
* if file cannot be read.
|
||||||
|
*/
|
||||||
|
public static Map<String, HostTxtEntry> parse(File file) throws IOException {
|
||||||
|
FileInputStream fileStream = null;
|
||||||
|
try {
|
||||||
|
fileStream = new FileInputStream(file);
|
||||||
|
BufferedReader input = new BufferedReader(new InputStreamReader(
|
||||||
|
fileStream, "UTF-8"));
|
||||||
|
Map<String, HostTxtEntry> rv = parse(input);
|
||||||
|
return rv;
|
||||||
|
} finally {
|
||||||
|
if (fileStream != null) {
|
||||||
|
try {
|
||||||
|
fileStream.close();
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a Map using the contents of the File file. If file cannot be read,
|
||||||
|
* use map instead, and write the result to where file should have been.
|
||||||
|
*
|
||||||
|
* Returned map will not contain null ("remove") entries.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* A File to attempt to parse.
|
||||||
|
* @param map
|
||||||
|
* A Map containing values to use as defaults.
|
||||||
|
* @return A Map containing the key, value pairs from file, or if file
|
||||||
|
* cannot be read, map.
|
||||||
|
*/
|
||||||
|
public static Map<String, HostTxtEntry> parse(File file, Map<String, HostTxtEntry> map) {
|
||||||
|
Map<String, HostTxtEntry> result;
|
||||||
|
try {
|
||||||
|
result = parse(file);
|
||||||
|
for (Map.Entry<String, HostTxtEntry> entry : map.entrySet()) {
|
||||||
|
if (!result.containsKey(entry.getKey()))
|
||||||
|
result.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
} catch (IOException exp) {
|
||||||
|
result = map;
|
||||||
|
try {
|
||||||
|
write(result, file);
|
||||||
|
} catch (IOException exp2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write contents of Map map to BufferedWriter output. Output is written
|
||||||
|
* with one key, value pair on each line, in the format: key=value.
|
||||||
|
*
|
||||||
|
* @param map
|
||||||
|
* A Map to write to output.
|
||||||
|
* @param output
|
||||||
|
* A BufferedWriter to write the Map to.
|
||||||
|
* @throws IOException
|
||||||
|
* if the BufferedWriter cannot be written to.
|
||||||
|
*/
|
||||||
|
private static void write(Map<String, HostTxtEntry> map, BufferedWriter output) throws IOException {
|
||||||
|
try {
|
||||||
|
for (Map.Entry<String, HostTxtEntry> entry : map.entrySet()) {
|
||||||
|
entry.getValue().write(output);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try { output.close(); } catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write contents of Map map to the File file. Output is written
|
||||||
|
* with one key, value pair on each line, in the format: key=value.
|
||||||
|
* Write to a temp file in the same directory and then rename, to not corrupt
|
||||||
|
* simultaneous accesses by the router. Except on Windows where renameTo()
|
||||||
|
* will fail if the target exists.
|
||||||
|
*
|
||||||
|
* @param map
|
||||||
|
* A Map to write to file.
|
||||||
|
* @param file
|
||||||
|
* A File to write the Map to.
|
||||||
|
* @throws IOException
|
||||||
|
* if file cannot be written to.
|
||||||
|
*/
|
||||||
|
public static void write(Map<String, HostTxtEntry> map, File file) throws IOException {
|
||||||
|
boolean success = false;
|
||||||
|
if (!isWindows) {
|
||||||
|
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
|
||||||
|
write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
||||||
|
success = tmp.renameTo(file);
|
||||||
|
if (!success) {
|
||||||
|
tmp.delete();
|
||||||
|
//System.out.println("Warning: addressbook rename fail from " + tmp + " to " + file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
// hmm, that didn't work, try it the old way
|
||||||
|
write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage: HostTxtParser [-q] validate example.i2p=b64dest[#!key1=val1#key2=val2]
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
boolean quiet = false;
|
||||||
|
if (args.length > 0 && args[0].equals("-q")) {
|
||||||
|
quiet = true;
|
||||||
|
args = java.util.Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
}
|
||||||
|
if (args.length != 2 || !args[0].equals("validate")) {
|
||||||
|
System.err.println("Usage: HostTxtParser validate example.i2p=b64dest[#!key1=val1#key2=val2]");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
HostTxtEntry e = parse(args[1].trim(), false);
|
||||||
|
if (e == null) {
|
||||||
|
if (!quiet)
|
||||||
|
System.err.println("Bad format");
|
||||||
|
System.exit(2);
|
||||||
|
}
|
||||||
|
if (!e.hasValidSig()) {
|
||||||
|
if (!quiet)
|
||||||
|
System.err.println("Bad signature");
|
||||||
|
System.exit(3);
|
||||||
|
}
|
||||||
|
Properties p = e.getProps();
|
||||||
|
if (p != null) {
|
||||||
|
if (p.containsKey(HostTxtEntry.PROP_ACTION) ||
|
||||||
|
p.containsKey(HostTxtEntry.PROP_OLDDEST) ||
|
||||||
|
p.containsKey(HostTxtEntry.PROP_OLDNAME) ||
|
||||||
|
p.containsKey(HostTxtEntry.PROP_OLDSIG)) {
|
||||||
|
if (!e.hasValidSig()) {
|
||||||
|
if (!quiet)
|
||||||
|
System.err.println("Bad inner signature");
|
||||||
|
System.exit(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!quiet)
|
||||||
|
System.err.println("Good signature for " + e.getName());
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
public static void test(String[] args) throws Exception {
|
||||||
|
File f = new File("tmp-hosts.txt");
|
||||||
|
Map<String, HostTxtEntry> map = parse(f);
|
||||||
|
for (HostTxtEntry e : map.values()) {
|
||||||
|
System.out.println("Host: " + e.getName() +
|
||||||
|
"\nDest: " + e.getDest() +
|
||||||
|
"\nAction: " + (e.getProps() != null ? e.getProps().getProperty("action") : "(none)") +
|
||||||
|
"\nValid Inner? " + e.hasValidInnerSig() +
|
||||||
|
"\nValid? " + e.hasValidSig() +
|
||||||
|
'\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
****/
|
||||||
|
}
|
||||||
@@ -23,8 +23,9 @@ package net.i2p.addressbook;
|
|||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,7 +36,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
class Log {
|
class Log {
|
||||||
|
|
||||||
private File file;
|
private final File file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Log instance that writes to the File file.
|
* Construct a Log instance that writes to the File file.
|
||||||
@@ -56,8 +57,8 @@ class Log {
|
|||||||
public void append(String entry) {
|
public void append(String entry) {
|
||||||
BufferedWriter bw = null;
|
BufferedWriter bw = null;
|
||||||
try {
|
try {
|
||||||
bw = new BufferedWriter(new FileWriter(this.file,
|
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.file,
|
||||||
true));
|
true), "UTF-8"));
|
||||||
String timestamp = new Date().toString();
|
String timestamp = new Date().toString();
|
||||||
bw.write(timestamp + " -- " + entry);
|
bw.write(timestamp + " -- " + entry);
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
@@ -73,7 +74,9 @@ class Log {
|
|||||||
*
|
*
|
||||||
* @return The File that the log is writing to.
|
* @return The File that the log is writing to.
|
||||||
*/
|
*/
|
||||||
|
/****
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return this.file;
|
return this.file;
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ package net.i2p.addressbook;
|
|||||||
*/
|
*/
|
||||||
class Subscription {
|
class Subscription {
|
||||||
|
|
||||||
private String location;
|
private final String location;
|
||||||
|
|
||||||
private String etag;
|
private String etag;
|
||||||
|
|
||||||
private String lastModified;
|
private String lastModified;
|
||||||
private long lastFetched;
|
private long lastFetched;
|
||||||
|
|
||||||
@@ -41,14 +39,15 @@ class Subscription {
|
|||||||
* was last read at the time represented by etag and lastModified.
|
* was last read at the time represented by etag and lastModified.
|
||||||
*
|
*
|
||||||
* @param location
|
* @param location
|
||||||
* A String representing a url to a remote address book.
|
* A String representing a url to a remote address book. Non-null.
|
||||||
* @param etag
|
* @param etag
|
||||||
* The etag header that we recieved the last time we read this
|
* The etag header that we received the last time we read this
|
||||||
* subscription.
|
* subscription. May be null.
|
||||||
* @param lastModified
|
* @param lastModified
|
||||||
* the last-modified header we recieved the last time we read
|
* the last-modified header we received the last time we read
|
||||||
* this subscription.
|
* this subscription. May be null.
|
||||||
* @param lastFetched when the subscription was last fetched (Java time, as a String)
|
* @param lastFetched when the subscription was last fetched (Java time, as a String).
|
||||||
|
* May be null.
|
||||||
*/
|
*/
|
||||||
public Subscription(String location, String etag, String lastModified, String lastFetched) {
|
public Subscription(String location, String etag, String lastModified, String lastFetched) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
@@ -71,7 +70,7 @@ class Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the etag header that we recieved the last time we read this
|
* Return the etag header that we received the last time we read this
|
||||||
* subscription.
|
* subscription.
|
||||||
*
|
*
|
||||||
* @return A String containing the etag header.
|
* @return A String containing the etag header.
|
||||||
@@ -91,7 +90,7 @@ class Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last-modified header that we recieved the last time we read
|
* Return the last-modified header that we received the last time we read
|
||||||
* this subscription.
|
* this subscription.
|
||||||
*
|
*
|
||||||
* @return A String containing the last-modified header.
|
* @return A String containing the last-modified header.
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.client.naming.HostTxtEntry;
|
||||||
|
import net.i2p.util.PortMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An iterator over the subscriptions in a SubscriptionList. Note that this iterator
|
* An iterator over the subscriptions in a SubscriptionList. Note that this iterator
|
||||||
@@ -36,9 +38,9 @@ import net.i2p.I2PAppContext;
|
|||||||
*/
|
*/
|
||||||
class SubscriptionIterator implements Iterator<AddressBook> {
|
class SubscriptionIterator implements Iterator<AddressBook> {
|
||||||
|
|
||||||
private Iterator<Subscription> subIterator;
|
private final Iterator<Subscription> subIterator;
|
||||||
private String proxyHost;
|
private final String proxyHost;
|
||||||
private int proxyPort;
|
private final int proxyPort;
|
||||||
private final long delay;
|
private final long delay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,11 +71,17 @@ class SubscriptionIterator implements Iterator<AddressBook> {
|
|||||||
* Yes, the EepGet fetch() is done in here in next().
|
* Yes, the EepGet fetch() is done in here in next().
|
||||||
*
|
*
|
||||||
* see java.util.Iterator#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() {
|
public AddressBook next() {
|
||||||
Subscription sub = this.subIterator.next();
|
Subscription sub = this.subIterator.next();
|
||||||
if (sub.getLastFetched() + this.delay < I2PAppContext.getGlobalContext().clock().now()) {
|
if (sub.getLocation().startsWith("file:")) {
|
||||||
|
// test only
|
||||||
|
return new AddressBook(sub.getLocation().substring(5));
|
||||||
|
} else 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());
|
//System.err.println("Fetching addressbook from " + sub.getLocation());
|
||||||
return new AddressBook(sub, this.proxyHost, this.proxyPort);
|
return new AddressBook(sub, this.proxyHost, this.proxyPort);
|
||||||
} else {
|
} else {
|
||||||
@@ -81,7 +89,7 @@ class SubscriptionIterator implements Iterator<AddressBook> {
|
|||||||
// DataHelper.formatDuration(I2PAppContext.getGlobalContext().clock().now() - sub.getLastFetched()) +
|
// DataHelper.formatDuration(I2PAppContext.getGlobalContext().clock().now() - sub.getLastFetched()) +
|
||||||
// " ago but the minimum delay is " +
|
// " ago but the minimum delay is " +
|
||||||
// DataHelper.formatDuration(this.delay));
|
// DataHelper.formatDuration(this.delay));
|
||||||
return new AddressBook(Collections.<String, String> emptyMap());
|
return new AddressBook(Collections.<String, HostTxtEntry>emptyMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ package net.i2p.addressbook;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -34,19 +35,15 @@ import java.util.Map;
|
|||||||
* @author Ragnarok
|
* @author Ragnarok
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SubscriptionList {
|
class SubscriptionList implements Iterable<AddressBook> {
|
||||||
|
|
||||||
private List<Subscription> subscriptions;
|
private final List<Subscription> subscriptions;
|
||||||
|
private final File etagsFile;
|
||||||
private File etagsFile;
|
private final File lastModifiedFile;
|
||||||
|
private final File lastFetchedFile;
|
||||||
private File lastModifiedFile;
|
|
||||||
private File lastFetchedFile;
|
|
||||||
private final long delay;
|
private final long delay;
|
||||||
|
private final String proxyHost;
|
||||||
private String proxyHost;
|
private final int proxyPort;
|
||||||
|
|
||||||
private int proxyPort;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a SubscriptionList using the urls from locationsFile and, if
|
* Construct a SubscriptionList using the urls from locationsFile and, if
|
||||||
@@ -69,7 +66,7 @@ class SubscriptionList {
|
|||||||
public SubscriptionList(File locationsFile, File etagsFile,
|
public SubscriptionList(File locationsFile, File etagsFile,
|
||||||
File lastModifiedFile, File lastFetchedFile, long delay, List<String> defaultSubs, String proxyHost,
|
File lastModifiedFile, File lastFetchedFile, long delay, List<String> defaultSubs, String proxyHost,
|
||||||
int proxyPort) {
|
int proxyPort) {
|
||||||
this.subscriptions = new LinkedList<Subscription>();
|
this.subscriptions = new ArrayList<Subscription>(4);
|
||||||
this.etagsFile = etagsFile;
|
this.etagsFile = etagsFile;
|
||||||
this.lastModifiedFile = lastModifiedFile;
|
this.lastModifiedFile = lastModifiedFile;
|
||||||
this.lastFetchedFile = lastFetchedFile;
|
this.lastFetchedFile = lastFetchedFile;
|
||||||
@@ -84,17 +81,17 @@ class SubscriptionList {
|
|||||||
try {
|
try {
|
||||||
etags = ConfigParser.parse(etagsFile);
|
etags = ConfigParser.parse(etagsFile);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {
|
||||||
etags = new HashMap<String, String>();
|
etags = Collections.<String, String>emptyMap();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
lastModified = ConfigParser.parse(lastModifiedFile);
|
lastModified = ConfigParser.parse(lastModifiedFile);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {
|
||||||
lastModified = new HashMap<String, String>();
|
lastModified = Collections.<String, String>emptyMap();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
lastFetched = ConfigParser.parse(lastFetchedFile);
|
lastFetched = ConfigParser.parse(lastFetchedFile);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {
|
||||||
lastFetched = new HashMap<String, String>();
|
lastFetched = Collections.<String, String>emptyMap();
|
||||||
}
|
}
|
||||||
for (String location : locations) {
|
for (String location : locations) {
|
||||||
this.subscriptions.add(new Subscription(location, etags.get(location),
|
this.subscriptions.add(new Subscription(location, etags.get(location),
|
||||||
@@ -103,6 +100,24 @@ class SubscriptionList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing only.
|
||||||
|
*
|
||||||
|
* @param hoststxt path to a local file used as the test 'subscription' input
|
||||||
|
* @since 0.9.26
|
||||||
|
*/
|
||||||
|
public SubscriptionList(String hoststxt) {
|
||||||
|
File dummy = new File("/dev/null");
|
||||||
|
this.etagsFile = dummy;
|
||||||
|
this.lastModifiedFile = dummy;
|
||||||
|
this.lastFetchedFile = dummy;
|
||||||
|
this.delay = 0;
|
||||||
|
this.proxyHost = "127.0.0.1";
|
||||||
|
this.proxyPort = 4444;
|
||||||
|
Subscription sub = new Subscription("file:" + hoststxt, null, null, null);
|
||||||
|
this.subscriptions = Collections.singletonList(sub);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an iterator over the AddressBooks represented by the Subscriptions
|
* Return an iterator over the AddressBooks represented by the Subscriptions
|
||||||
* in this SubscriptionList.
|
* in this SubscriptionList.
|
||||||
@@ -121,9 +136,10 @@ class SubscriptionList {
|
|||||||
* won't be read back correctly; the '=' should be escaped.
|
* won't be read back correctly; the '=' should be escaped.
|
||||||
*/
|
*/
|
||||||
public void write() {
|
public void write() {
|
||||||
Map<String, String> etags = new HashMap<String, String>();
|
int sz = subscriptions.size();
|
||||||
Map<String, String> lastModified = new HashMap<String, String>();
|
Map<String, String> etags = new HashMap<String, String>(sz);
|
||||||
Map<String, String> lastFetched = new HashMap<String, String>();
|
Map<String, String> lastModified = new HashMap<String, String>(sz);
|
||||||
|
Map<String, String> lastFetched = new HashMap<String, String>(sz);
|
||||||
for (Subscription sub : this.subscriptions) {
|
for (Subscription sub : this.subscriptions) {
|
||||||
if (sub.getEtag() != null) {
|
if (sub.getEtag() != null) {
|
||||||
etags.put(sub.getLocation(), sub.getEtag());
|
etags.put(sub.getLocation(), sub.getEtag());
|
||||||
@@ -131,13 +147,16 @@ class SubscriptionList {
|
|||||||
if (sub.getLastModified() != null) {
|
if (sub.getLastModified() != null) {
|
||||||
lastModified.put(sub.getLocation(), sub.getLastModified());
|
lastModified.put(sub.getLocation(), sub.getLastModified());
|
||||||
}
|
}
|
||||||
lastFetched.put(sub.getLocation(), "" + sub.getLastFetched());
|
lastFetched.put(sub.getLocation(), Long.toString(sub.getLastFetched()));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ConfigParser.write(etags, this.etagsFile);
|
ConfigParser.write(etags, this.etagsFile);
|
||||||
|
} catch (IOException exp) {}
|
||||||
|
try {
|
||||||
ConfigParser.write(lastModified, this.lastModifiedFile);
|
ConfigParser.write(lastModified, this.lastModifiedFile);
|
||||||
|
} catch (IOException exp) {}
|
||||||
|
try {
|
||||||
ConfigParser.write(lastFetched, this.lastFetchedFile);
|
ConfigParser.write(lastFetched, this.lastFetchedFile);
|
||||||
} catch (IOException exp) {
|
} catch (IOException exp) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -36,8 +36,8 @@ import java.io.IOException;
|
|||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
public class RAIFile implements RandomAccessInterface, DataInput, DataOutput {
|
public class RAIFile implements RandomAccessInterface, DataInput, DataOutput {
|
||||||
private File f;
|
private final File f;
|
||||||
private RandomAccessFile delegate;
|
private final RandomAccessFile delegate;
|
||||||
private final boolean r, w;
|
private final boolean r, w;
|
||||||
|
|
||||||
public RAIFile(RandomAccessFile file) throws FileNotFoundException {
|
public RAIFile(RandomAccessFile file) throws FileNotFoundException {
|
||||||
@@ -28,9 +28,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.io;
|
package net.metanotion.io;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface RandomAccessInterface {
|
public interface RandomAccessInterface extends Closeable {
|
||||||
public long getFilePointer() throws IOException;
|
public long getFilePointer() throws IOException;
|
||||||
public long length() throws IOException;
|
public long length() throws IOException;
|
||||||
public int read() throws IOException;
|
public int read() throws IOException;
|
||||||
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.io;
|
package net.metanotion.io;
|
||||||
|
|
||||||
public interface Serializer {
|
public interface Serializer<T> {
|
||||||
public byte[] getBytes(Object o);
|
public byte[] getBytes(T o);
|
||||||
public Object construct(byte[] b);
|
public T construct(byte[] b);
|
||||||
}
|
}
|
||||||
@@ -28,11 +28,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.io.block;
|
package net.metanotion.io.block;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.metanotion.io.RAIFile;
|
import net.metanotion.io.RAIFile;
|
||||||
@@ -64,7 +68,7 @@ import net.i2p.util.Log;
|
|||||||
* Pages are 1 KB and are numbered starting from 1.
|
* Pages are 1 KB and are numbered starting from 1.
|
||||||
* e.g. the Metaindex skiplist is at offset 1024 bytes
|
* e.g. the Metaindex skiplist is at offset 1024 bytes
|
||||||
*/
|
*/
|
||||||
public class BlockFile {
|
public class BlockFile implements Closeable {
|
||||||
public static final int PAGESIZE = 1024;
|
public static final int PAGESIZE = 1024;
|
||||||
public static final long OFFSET_MOUNTED = 20;
|
public static final long OFFSET_MOUNTED = 20;
|
||||||
public final Log log = I2PAppContext.getGlobalContext().logManager().getLog(BlockFile.class);
|
public final Log log = I2PAppContext.getGlobalContext().logManager().getLog(BlockFile.class);
|
||||||
@@ -93,7 +97,7 @@ public class BlockFile {
|
|||||||
/** I2P was the file locked when we opened it? */
|
/** I2P was the file locked when we opened it? */
|
||||||
private final boolean _wasMounted;
|
private final boolean _wasMounted;
|
||||||
|
|
||||||
private final BSkipList metaIndex;
|
private final BSkipList<String, Integer> metaIndex;
|
||||||
private boolean _isClosed;
|
private boolean _isClosed;
|
||||||
/** cached list of free pages, only valid if freListStart > 0 */
|
/** cached list of free pages, only valid if freListStart > 0 */
|
||||||
private FreeListBlock flb;
|
private FreeListBlock flb;
|
||||||
@@ -146,7 +150,7 @@ public class BlockFile {
|
|||||||
bf.bfck(true);
|
bf.bfck(true);
|
||||||
bf.close();
|
bf.close();
|
||||||
raif.close();
|
raif.close();
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,7 +323,7 @@ public class BlockFile {
|
|||||||
if (rai.canWrite())
|
if (rai.canWrite())
|
||||||
mount();
|
mount();
|
||||||
|
|
||||||
metaIndex = new BSkipList(spanSize, this, METAINDEX_PAGE, new StringBytes(), new IntBytes());
|
metaIndex = new BSkipList<String, Integer>(spanSize, this, METAINDEX_PAGE, new StringBytes(), new IntBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,7 +337,7 @@ public class BlockFile {
|
|||||||
/**
|
/**
|
||||||
* Go to any page but the superblock.
|
* Go to any page but the superblock.
|
||||||
* Page 1 is the superblock, must use file.seek(0) to get there.
|
* Page 1 is the superblock, must use file.seek(0) to get there.
|
||||||
* @param page >= 2
|
* @param page >= 2
|
||||||
*/
|
*/
|
||||||
public static void pageSeek(RandomAccessInterface file, int page) throws IOException {
|
public static void pageSeek(RandomAccessInterface file, int page) throws IOException {
|
||||||
if (page < METAINDEX_PAGE)
|
if (page < METAINDEX_PAGE)
|
||||||
@@ -430,18 +434,25 @@ public class BlockFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Open a skiplist if it exists.
|
||||||
|
* Returns null if the skiplist does not exist.
|
||||||
|
* Empty skiplists are not preserved after close.
|
||||||
|
*
|
||||||
* If the file is writable, this runs an integrity check and repair
|
* If the file is writable, this runs an integrity check and repair
|
||||||
* on first open.
|
* on first open.
|
||||||
|
*
|
||||||
|
* @return null if not found
|
||||||
*/
|
*/
|
||||||
public BSkipList getIndex(String name, Serializer key, Serializer val) throws IOException {
|
@SuppressWarnings("unchecked")
|
||||||
|
public <K extends Comparable<? super K>, V> BSkipList<K, V> getIndex(String name, Serializer<K> key, Serializer<V> val) throws IOException {
|
||||||
// added I2P
|
// added I2P
|
||||||
BSkipList bsl = openIndices.get(name);
|
BSkipList<K, V> bsl = (BSkipList<K, V>) openIndices.get(name);
|
||||||
if (bsl != null)
|
if (bsl != null)
|
||||||
return bsl;
|
return bsl;
|
||||||
|
|
||||||
Integer page = (Integer) metaIndex.get(name);
|
Integer page = metaIndex.get(name);
|
||||||
if (page == null) { return null; }
|
if (page == null) { return null; }
|
||||||
bsl = new BSkipList(spanSize, this, page.intValue(), key, val, true);
|
bsl = new BSkipList<K, V>(spanSize, this, page.intValue(), key, val, true);
|
||||||
if (file.canWrite()) {
|
if (file.canWrite()) {
|
||||||
log.info("Checking skiplist " + name + " in blockfile " + file);
|
log.info("Checking skiplist " + name + " in blockfile " + file);
|
||||||
if (bsl.bslck(true, false))
|
if (bsl.bslck(true, false))
|
||||||
@@ -453,25 +464,43 @@ public class BlockFile {
|
|||||||
return bsl;
|
return bsl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BSkipList makeIndex(String name, Serializer key, Serializer val) throws IOException {
|
/**
|
||||||
|
* Create and open a new skiplist if it does not exist.
|
||||||
|
* Throws IOException if it already exists.
|
||||||
|
*
|
||||||
|
* @throws IOException if already exists or other errors
|
||||||
|
*/
|
||||||
|
public <K extends Comparable<? super K>, V> BSkipList<K, V> makeIndex(String name, Serializer<K> key, Serializer<V> val) throws IOException {
|
||||||
if(metaIndex.get(name) != null) { throw new IOException("Index already exists"); }
|
if(metaIndex.get(name) != null) { throw new IOException("Index already exists"); }
|
||||||
int page = allocPage();
|
int page = allocPage();
|
||||||
metaIndex.put(name, Integer.valueOf(page));
|
metaIndex.put(name, Integer.valueOf(page));
|
||||||
BSkipList.init(this, page, spanSize);
|
BSkipList.init(this, page, spanSize);
|
||||||
BSkipList bsl = new BSkipList(spanSize, this, page, key, val, true);
|
BSkipList<K, V> bsl = new BSkipList<K, V>(spanSize, this, page, key, val, true);
|
||||||
openIndices.put(name, bsl);
|
openIndices.put(name, bsl);
|
||||||
return bsl;
|
return bsl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a skiplist if it exists.
|
||||||
|
* Must be open. Throws IOException if exists but is closed.
|
||||||
|
* Broken before 0.9.26.
|
||||||
|
*
|
||||||
|
* @throws IOException if it is closed.
|
||||||
|
*/
|
||||||
public void delIndex(String name) throws IOException {
|
public void delIndex(String name) throws IOException {
|
||||||
Integer page = (Integer) metaIndex.remove(name);
|
if (metaIndex.get(name) == null)
|
||||||
if (page == null) { return; }
|
return;
|
||||||
Serializer nb = new IdentityBytes();
|
BSkipList bsl = openIndices.get(name);
|
||||||
BSkipList bsl = new BSkipList(spanSize, this, page.intValue(), nb, nb, true);
|
if (bsl == null)
|
||||||
|
throw new IOException("Cannot delete closed skiplist, open it first: " + name);
|
||||||
bsl.delete();
|
bsl.delete();
|
||||||
|
openIndices.remove(name);
|
||||||
|
metaIndex.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Close a skiplist if it is open.
|
||||||
|
*
|
||||||
* Added I2P
|
* Added I2P
|
||||||
*/
|
*/
|
||||||
public void closeIndex(String name) {
|
public void closeIndex(String name) {
|
||||||
@@ -481,8 +510,75 @@ public class BlockFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Reformat a skiplist with new Serializers if it exists.
|
||||||
|
* The skiplist must be closed.
|
||||||
|
* Throws IOException if the skiplist is open.
|
||||||
|
* The skiplist will remain closed after completion.
|
||||||
|
*
|
||||||
|
* @throws IOException if it is open or on errors
|
||||||
|
* @since 0.9.26
|
||||||
|
*/
|
||||||
|
public <K extends Comparable<? super K>, V> void reformatIndex(String name, Serializer<K> oldKey, Serializer<V> oldVal,
|
||||||
|
Serializer<K> newKey, Serializer<V> newVal) throws IOException {
|
||||||
|
if (openIndices.containsKey(name))
|
||||||
|
throw new IOException("Cannot reformat open skiplist " + name);
|
||||||
|
BSkipList<K, V> old = getIndex(name, oldKey, oldVal);
|
||||||
|
if (old == null)
|
||||||
|
return;
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
String tmpName = "---tmp---" + name + "---tmp---";
|
||||||
|
BSkipList<K, V> tmp = getIndex(tmpName, newKey, newVal);
|
||||||
|
if (tmp != null) {
|
||||||
|
log.logAlways(Log.WARN, "Continuing on aborted reformat of list " + name);
|
||||||
|
} else {
|
||||||
|
tmp = makeIndex(tmpName, newKey, newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It could be much more efficient to do this at the
|
||||||
|
// SkipSpan layer but that's way too hard.
|
||||||
|
final int loop = 32;
|
||||||
|
List<K> keys = new ArrayList<K>(loop);
|
||||||
|
List<V> vals = new ArrayList<V>(loop);
|
||||||
|
while (true) {
|
||||||
|
SkipIterator<K, V> iter = old.iterator();
|
||||||
|
for (int i = 0; iter.hasNext() && i < loop; i++) {
|
||||||
|
try {
|
||||||
|
keys.add(iter.nextKey());
|
||||||
|
vals.add(iter.next());
|
||||||
|
} catch (NoSuchElementException nsee) {
|
||||||
|
throw new IOException("Unable to reformat corrupt list " + name, nsee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// save state, as deleting corrupts the iterator
|
||||||
|
boolean done = !iter.hasNext();
|
||||||
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
|
tmp.put(keys.get(i), vals.get(i));
|
||||||
|
}
|
||||||
|
for (int i = keys.size() - 1; i >= 0; i--) {
|
||||||
|
old.remove(keys.get(i));
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
keys.clear();
|
||||||
|
vals.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
delIndex(name);
|
||||||
|
closeIndex(name);
|
||||||
|
closeIndex(tmpName);
|
||||||
|
Integer page = metaIndex.get(tmpName);
|
||||||
|
metaIndex.put(name, page);
|
||||||
|
metaIndex.remove(tmpName);
|
||||||
|
if (log.shouldWarn())
|
||||||
|
log.warn("reformatted list: " + name + " in " +
|
||||||
|
(System.currentTimeMillis() - start) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes all open skiplists and then the blockfile itself.
|
||||||
|
*
|
||||||
* Note (I2P)
|
* Note (I2P)
|
||||||
* Does NOT close the RAF / RAI.
|
* Does NOT close the RAF / RAI.
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
// added I2P
|
// added I2P
|
||||||
@@ -538,9 +634,15 @@ public class BlockFile {
|
|||||||
try {
|
try {
|
||||||
// This uses IdentityBytes, so the value class won't be right, but at least
|
// This uses IdentityBytes, so the value class won't be right, but at least
|
||||||
// it won't fail the out-of-order check
|
// it won't fail the out-of-order check
|
||||||
Serializer keyser = slname.equals("%%__REVERSE__%%") ? new IntBytes() : new UTF8StringBytes();
|
boolean fail;
|
||||||
BSkipList bsl = getIndex(slname, keyser, new IdentityBytes());
|
if (slname.equals("%%__REVERSE__%%")) {
|
||||||
if (bsl == null) {
|
Serializer<Integer> keyser = new IntBytes();
|
||||||
|
fail = getIndex(slname, keyser, new IdentityBytes()) == null;
|
||||||
|
} else {
|
||||||
|
Serializer<String> keyser = new UTF8StringBytes();
|
||||||
|
fail = getIndex(slname, keyser, new IdentityBytes()) == null;
|
||||||
|
}
|
||||||
|
if (fail) {
|
||||||
log.error("Can't find list? " + slname);
|
log.error("Can't find list? " + slname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,9 @@ package net.metanotion.io.block.index;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@@ -53,16 +55,26 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
* Always fits on one page.
|
* Always fits on one page.
|
||||||
*/
|
*/
|
||||||
public class BSkipLevels extends SkipLevels {
|
public class BSkipLevels<K extends Comparable<? super K>, V> extends SkipLevels<K, V> {
|
||||||
private static final long MAGIC = 0x42534c6576656c73l; // "BSLevels"
|
private static final long MAGIC = 0x42534c6576656c73l; // "BSLevels"
|
||||||
static final int HEADER_LEN = 16;
|
static final int HEADER_LEN = 16;
|
||||||
public final int levelPage;
|
public final int levelPage;
|
||||||
public final int spanPage;
|
public final int spanPage;
|
||||||
public final BlockFile bf;
|
public final BlockFile bf;
|
||||||
private final BSkipList bsl;
|
private final BSkipList<K, V> bsl;
|
||||||
private boolean isKilled;
|
private boolean isKilled;
|
||||||
|
// the level pages, passed from the constructor to initializeLevels(),
|
||||||
|
// NOT kept up to date
|
||||||
|
private final int[] lps;
|
||||||
|
|
||||||
public BSkipLevels(BlockFile bf, int levelPage, BSkipList bsl) throws IOException {
|
/**
|
||||||
|
* Non-recursive initializer initializeLevels()
|
||||||
|
* MUST be called on the first BSkipLevel in the skiplist
|
||||||
|
* after the constructor, unless it's a new empty
|
||||||
|
* level and init() was previously called.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BSkipLevels(BlockFile bf, int levelPage, BSkipList<K, V> bsl) throws IOException {
|
||||||
this.levelPage = levelPage;
|
this.levelPage = levelPage;
|
||||||
this.bf = bf;
|
this.bf = bf;
|
||||||
this.bsl = bsl;
|
this.bsl = bsl;
|
||||||
@@ -86,27 +98,59 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
throw new IOException("No span found in cache???");
|
throw new IOException("No span found in cache???");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.levels = new BSkipLevels[maxLen];
|
this.levels = (BSkipLevels<K, V>[]) new BSkipLevels[maxLen];
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Reading New BSkipLevels with " + nonNull + " / " + maxLen + " valid levels page " + levelPage);
|
bf.log.debug("Reading New BSkipLevels with " + nonNull + " / " + maxLen + " valid levels page " + levelPage +
|
||||||
|
" in skiplist " + bsl);
|
||||||
// We have to read now because new BSkipLevels() will move the file pointer
|
// We have to read now because new BSkipLevels() will move the file pointer
|
||||||
int[] lps = new int[nonNull];
|
lps = new int[nonNull];
|
||||||
for(int i = 0; i < nonNull; i++) {
|
for(int i = 0; i < nonNull; i++) {
|
||||||
lps[i] = bf.file.readUnsignedInt();
|
lps[i] = bf.file.readUnsignedInt();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-recursive initializer.
|
||||||
|
* MUST be called on the first BSkipLevel in the skiplist
|
||||||
|
* after the constructor, unless it's a new empty
|
||||||
|
* level and init() was previously called.
|
||||||
|
* Only call on the first skiplevel in the list!
|
||||||
|
*
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public void initializeLevels() {
|
||||||
|
List<BSkipLevels<K, V>> toInit = new ArrayList<BSkipLevels<K, V>>(32);
|
||||||
|
List<BSkipLevels<K, V>> nextInit = new ArrayList<BSkipLevels<K, V>>(32);
|
||||||
|
initializeLevels(toInit);
|
||||||
|
while (!toInit.isEmpty()) {
|
||||||
|
for (BSkipLevels<K, V> bsl : toInit) {
|
||||||
|
bsl.initializeLevels(nextInit);
|
||||||
|
}
|
||||||
|
List<BSkipLevels<K, V>> tmp = toInit;
|
||||||
|
toInit = nextInit;
|
||||||
|
nextInit = tmp;
|
||||||
|
nextInit.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-recursive initializer.
|
||||||
|
* MUST be called after constructor.
|
||||||
|
*
|
||||||
|
* @param nextInit out parameter, next levels to initialize
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
private void initializeLevels(List<BSkipLevels<K, V>> nextInit) {
|
||||||
boolean fail = false;
|
boolean fail = false;
|
||||||
for(int i = 0; i < nonNull; i++) {
|
for(int i = 0; i < lps.length; i++) {
|
||||||
int lp = lps[i];
|
int lp = lps[i];
|
||||||
if(lp != 0) {
|
if(lp != 0) {
|
||||||
levels[i] = bsl.levelHash.get(Integer.valueOf(lp));
|
levels[i] = bsl.levelHash.get(Integer.valueOf(lp));
|
||||||
if(levels[i] == null) {
|
if(levels[i] == null) {
|
||||||
try {
|
try {
|
||||||
// FIXME this will explode the stack if too big
|
BSkipLevels<K, V> lev = new BSkipLevels<K, V>(bf, lp, bsl);
|
||||||
// Redo this without recursion?
|
levels[i] = lev;
|
||||||
// Lots of recursion in super to be fixed also...
|
nextInit.add(lev);
|
||||||
levels[i] = new BSkipLevels(bf, lp, bsl);
|
|
||||||
bsl.levelHash.put(Integer.valueOf(lp), levels[i]);
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
bf.log.error("Corrupt database, bad level " + i +
|
bf.log.error("Corrupt database, bad level " + i +
|
||||||
" at page " + lp, ioe);
|
" at page " + lp, ioe);
|
||||||
@@ -115,8 +159,8 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Comparable ourKey = key();
|
K ourKey = key();
|
||||||
Comparable nextKey = levels[i].key();
|
K nextKey = levels[i].key();
|
||||||
if (ourKey != null && nextKey != null &&
|
if (ourKey != null && nextKey != null &&
|
||||||
ourKey.compareTo(nextKey) >= 0) {
|
ourKey.compareTo(nextKey) >= 0) {
|
||||||
bf.log.warn("Corrupt database, level out of order " + this +
|
bf.log.warn("Corrupt database, level out of order " + this +
|
||||||
@@ -129,7 +173,9 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
// TODO also check that the level[] array is not out-of-order
|
// TODO also check that the level[] array is not out-of-order
|
||||||
} else {
|
} else {
|
||||||
if (bf.log.shouldLog(Log.WARN))
|
if (bf.log.shouldLog(Log.WARN))
|
||||||
bf.log.warn("WTF " + this + " i = " + i + " of " + nonNull + " / " + maxLen + " valid levels but page is zero");
|
bf.log.warn(this + " i = " + i + " of " +
|
||||||
|
lps.length + " / " + levels.length +
|
||||||
|
" valid levels but page is zero");
|
||||||
levels[i] = null;
|
levels[i] = null;
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
@@ -170,9 +216,9 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bf.file.writeShort(i);
|
bf.file.writeShort(i);
|
||||||
bf.file.writeInt(((BSkipSpan) bottom).page);
|
bf.file.writeInt(((BSkipSpan<K, V>) bottom).page);
|
||||||
for(int j = 0; j < i; j++) {
|
for(int j = 0; j < i; j++) {
|
||||||
bf.file.writeInt(((BSkipLevels) levels[j]).levelPage);
|
bf.file.writeInt(((BSkipLevels<K, V>) levels[j]).levelPage);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) { throw new RuntimeException("Error writing to database", ioe); }
|
} catch (IOException ioe) { throw new RuntimeException("Error writing to database", ioe); }
|
||||||
}
|
}
|
||||||
@@ -184,22 +230,23 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Killing " + this + ' ' + print(), new Exception());
|
bf.log.debug("Killing " + this + ' ' + print() /* , new Exception() */ );
|
||||||
isKilled = true;
|
isKilled = true;
|
||||||
bsl.levelHash.remove(Integer.valueOf(levelPage));
|
bsl.levelHash.remove(Integer.valueOf(levelPage));
|
||||||
bf.freePage(levelPage);
|
bf.freePage(levelPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipLevels newInstance(int levels, SkipSpan ss, SkipList sl) {
|
public SkipLevels<K, V> newInstance(int levels, SkipSpan<K, V> ss, SkipList<K, V> sl) {
|
||||||
try {
|
try {
|
||||||
BSkipSpan bss = (BSkipSpan) ss;
|
BSkipSpan<K, V> bss = (BSkipSpan<K, V>) ss;
|
||||||
BSkipList bsl = (BSkipList) sl;
|
BSkipList<K, V> bsl = (BSkipList<K, V>) sl;
|
||||||
int page = bf.allocPage();
|
int page = bf.allocPage();
|
||||||
BSkipLevels.init(bf, page, bss.page, levels);
|
BSkipLevels.init(bf, page, bss.page, levels);
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("New BSkipLevels height " + levels + " page " + page);
|
bf.log.debug("New BSkipLevels height " + levels + " page " + page);
|
||||||
return new BSkipLevels(bf, page, bsl);
|
return new BSkipLevels<K, V>(bf, page, bsl);
|
||||||
|
// do not need to call initLevels() here
|
||||||
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +274,7 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
* @since 0.8.8
|
* @since 0.8.8
|
||||||
*/
|
*/
|
||||||
private boolean blvlfix() {
|
private boolean blvlfix() {
|
||||||
TreeSet<SkipLevels> lvls = new TreeSet<SkipLevels>(new LevelComparator());
|
TreeSet<SkipLevels<K, V>> lvls = new TreeSet<SkipLevels<K, V>>(new LevelComparator<K, V>());
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Starting level search");
|
bf.log.debug("Starting level search");
|
||||||
getAllLevels(this, lvls);
|
getAllLevels(this, lvls);
|
||||||
@@ -239,15 +286,15 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
}
|
}
|
||||||
// traverse the levels, back-to-front
|
// traverse the levels, back-to-front
|
||||||
boolean rv = false;
|
boolean rv = false;
|
||||||
SkipLevels after = null;
|
SkipLevels<K, V> after = null;
|
||||||
for (SkipLevels lv : lvls) {
|
for (SkipLevels<K, V> lv : lvls) {
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Checking " + lv.print());
|
bf.log.debug("Checking " + lv.print());
|
||||||
if (after != null) {
|
if (after != null) {
|
||||||
int min = Math.min(after.levels.length, lv.levels.length);
|
int min = Math.min(after.levels.length, lv.levels.length);
|
||||||
for (int i = 0; i < min; i++) {
|
for (int i = 0; i < min; i++) {
|
||||||
SkipLevels cur = lv.levels[i];
|
SkipLevels<K, V> cur = lv.levels[i];
|
||||||
if (cur != after) {
|
if (cur != after) {
|
||||||
if (cur != null)
|
if (cur != null)
|
||||||
bf.log.warn("Level " + i + " was wrong, fixing for " + lv.print());
|
bf.log.warn("Level " + i + " was wrong, fixing for " + lv.print());
|
||||||
@@ -285,12 +332,12 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
* @param lvlSet out parameter, the result
|
* @param lvlSet out parameter, the result
|
||||||
* @since 0.8.8
|
* @since 0.8.8
|
||||||
*/
|
*/
|
||||||
private void getAllLevels(SkipLevels l, Set<SkipLevels> lvlSet) {
|
private void getAllLevels(SkipLevels<K, V> l, Set<SkipLevels<K, V>> lvlSet) {
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("GAL " + l.print());
|
bf.log.debug("GAL " + l.print());
|
||||||
// Do level 0 without recursion, on the assumption everything is findable
|
// Do level 0 without recursion, on the assumption everything is findable
|
||||||
// from the root
|
// from the root
|
||||||
SkipLevels cur = l;
|
SkipLevels<K, V> cur = l;
|
||||||
while (cur != null && lvlSet.add(cur)) {
|
while (cur != null && lvlSet.add(cur)) {
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Adding " + cur.print());
|
bf.log.debug("Adding " + cur.print());
|
||||||
@@ -301,7 +348,7 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
// If there were no nulls at level 0 in the middle,
|
// If there were no nulls at level 0 in the middle,
|
||||||
// i.e. there are no problems, this won't find anything
|
// i.e. there are no problems, this won't find anything
|
||||||
for (int i = 1; i < l.levels.length; i++) {
|
for (int i = 1; i < l.levels.length; i++) {
|
||||||
SkipLevels lv = l.levels[i];
|
SkipLevels<K, V> lv = l.levels[i];
|
||||||
if (lv != null && !lvlSet.contains(lv))
|
if (lv != null && !lvlSet.contains(lv))
|
||||||
getAllLevels(lv, lvlSet);
|
getAllLevels(lv, lvlSet);
|
||||||
}
|
}
|
||||||
@@ -312,10 +359,10 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
* Sorts in REVERSE order.
|
* Sorts in REVERSE order.
|
||||||
* @since 0.8.8
|
* @since 0.8.8
|
||||||
*/
|
*/
|
||||||
private static class LevelComparator implements Comparator<SkipLevels>, Serializable {
|
private static class LevelComparator<K extends Comparable<? super K>, V> implements Comparator<SkipLevels<K, V>>, Serializable {
|
||||||
public int compare(SkipLevels l, SkipLevels r) {
|
public int compare(SkipLevels<K, V> l, SkipLevels<K, V> r) {
|
||||||
Comparable lk = l.key();
|
K lk = l.key();
|
||||||
Comparable rk = r.key();
|
K rk = r.key();
|
||||||
if (lk == null && rk == null)
|
if (lk == null && rk == null)
|
||||||
return 0;
|
return 0;
|
||||||
if (lk == null)
|
if (lk == null)
|
||||||
@@ -332,13 +379,14 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
* This needs work.
|
* This needs work.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean blvlck(boolean fix, int width, SkipLevels[] prevLevels) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public boolean blvlck(boolean fix, int width, SkipLevels<K, V>[] prevLevels) {
|
||||||
bf.log.warn(" Skip level at width " + width);
|
bf.log.warn(" Skip level at width " + width);
|
||||||
bf.log.warn(" levels " + this.levels.length);
|
bf.log.warn(" levels " + this.levels.length);
|
||||||
bf.log.warn(" first key " + this.key());
|
bf.log.warn(" first key " + this.key());
|
||||||
bf.log.warn(" spanPage " + this.spanPage);
|
bf.log.warn(" spanPage " + this.spanPage);
|
||||||
bf.log.warn(" levelPage " + this.levelPage);
|
bf.log.warn(" levelPage " + this.levelPage);
|
||||||
SkipLevels higher = null;
|
SkipLevels<K, V> higher = null;
|
||||||
for (int i = levels.length - 1; i >= 0; i--) {
|
for (int i = levels.length - 1; i >= 0; i--) {
|
||||||
if (levels[i] != null) {
|
if (levels[i] != null) {
|
||||||
bf.log.info(" level " + i + " -> " + levels[i].key() + " ");
|
bf.log.info(" level " + i + " -> " + levels[i].key() + " ");
|
||||||
@@ -372,7 +420,7 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prevLevels = new SkipLevels[levels.length];
|
prevLevels = (SkipLevels<K, V>[]) new SkipLevels[levels.length];
|
||||||
System.arraycopy(levels, 0, prevLevels, 0, levels.length);
|
System.arraycopy(levels, 0, prevLevels, 0, levels.length);
|
||||||
}
|
}
|
||||||
if (levels[0] != null)
|
if (levels[0] != null)
|
||||||
@@ -382,7 +430,8 @@ public class BSkipLevels extends SkipLevels {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String rv = "BSL height: " + levels.length + " page: " + levelPage + " span: " + bottom;
|
String rv = "BSLevel height: " + levels.length + " page: " + levelPage + " span: " + bottom +
|
||||||
|
" in skiplist " + bsl;
|
||||||
if (isKilled)
|
if (isKilled)
|
||||||
rv += " KILLED";
|
rv += " KILLED";
|
||||||
return rv;
|
return rv;
|
||||||
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.io.block.index;
|
package net.metanotion.io.block.index;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
* Always fits on one page.
|
* Always fits on one page.
|
||||||
*/
|
*/
|
||||||
public class BSkipList extends SkipList {
|
public class BSkipList<K extends Comparable<? super K>, V> extends SkipList<K, V> implements Closeable {
|
||||||
private static final long MAGIC = 0x536b69704c697374l; // "SkipList"
|
private static final long MAGIC = 0x536b69704c697374l; // "SkipList"
|
||||||
public int firstSpanPage = 0;
|
public int firstSpanPage = 0;
|
||||||
public int firstLevelPage = 0;
|
public int firstLevelPage = 0;
|
||||||
@@ -58,16 +59,16 @@ public class BSkipList extends SkipList {
|
|||||||
public final BlockFile bf;
|
public final BlockFile bf;
|
||||||
private boolean isClosed;
|
private boolean isClosed;
|
||||||
|
|
||||||
final HashMap<Integer, BSkipSpan> spanHash = new HashMap<Integer, BSkipSpan>();
|
final HashMap<Integer, BSkipSpan<K, V>> spanHash = new HashMap<Integer, BSkipSpan<K, V>>();
|
||||||
final HashMap<Integer, SkipLevels> levelHash = new HashMap<Integer, SkipLevels>();
|
final HashMap<Integer, SkipLevels<K, V>> levelHash = new HashMap<Integer, SkipLevels<K, V>>();
|
||||||
|
|
||||||
private final boolean fileOnly;
|
private final boolean fileOnly;
|
||||||
|
|
||||||
public BSkipList(int spanSize, BlockFile bf, int skipPage, Serializer key, Serializer val) throws IOException {
|
public BSkipList(int spanSize, BlockFile bf, int skipPage, Serializer<K> key, Serializer<V> val) throws IOException {
|
||||||
this(spanSize, bf, skipPage, key, val, false);
|
this(spanSize, bf, skipPage, key, val, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BSkipList(int spanSize, BlockFile bf, int skipPage, Serializer key, Serializer val, boolean fileOnly) throws IOException {
|
public BSkipList(int spanSize, BlockFile bf, int skipPage, Serializer<K> key, Serializer<V> val, boolean fileOnly) throws IOException {
|
||||||
if(spanSize < 1) { throw new RuntimeException("Span size too small"); }
|
if(spanSize < 1) { throw new RuntimeException("Span size too small"); }
|
||||||
|
|
||||||
this.skipPage = skipPage;
|
this.skipPage = skipPage;
|
||||||
@@ -88,10 +89,12 @@ public class BSkipList extends SkipList {
|
|||||||
|
|
||||||
this.fileOnly = fileOnly;
|
this.fileOnly = fileOnly;
|
||||||
if (fileOnly)
|
if (fileOnly)
|
||||||
first = new IBSkipSpan(bf, this, firstSpanPage, key, val);
|
first = new IBSkipSpan<K, V>(bf, this, firstSpanPage, key, val);
|
||||||
else
|
else
|
||||||
first = new BSkipSpan(bf, this, firstSpanPage, key, val);
|
first = new BSkipSpan<K, V>(bf, this, firstSpanPage, key, val);
|
||||||
stack = new BSkipLevels(bf, firstLevelPage, this);
|
BSkipLevels<K, V> bstack = new BSkipLevels<K, V>(bf, firstLevelPage, this);
|
||||||
|
bstack.initializeLevels();
|
||||||
|
stack = bstack;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
for (BSkipSpan ss : spanHash.values()) {
|
for (BSkipSpan ss : spanHash.values()) {
|
||||||
total += ss.nKeys;
|
total += ss.nKeys;
|
||||||
@@ -101,7 +104,8 @@ public class BSkipList extends SkipList {
|
|||||||
if (bf.file.canWrite() &&
|
if (bf.file.canWrite() &&
|
||||||
(levelCount != levelHash.size() || spans != spanHash.size() || size != total)) {
|
(levelCount != levelHash.size() || spans != spanHash.size() || size != total)) {
|
||||||
if (bf.log.shouldLog(Log.WARN))
|
if (bf.log.shouldLog(Log.WARN))
|
||||||
bf.log.warn("On-disk counts were " + levelCount + " / " + spans + " / " + size + ", correcting");
|
bf.log.warn("On-disk counts were " + levelCount + " levels / " + spans +
|
||||||
|
" spans / " + size + " entries, correcting to " + total + " entries");
|
||||||
size = total;
|
size = total;
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
@@ -148,7 +152,6 @@ public class BSkipList extends SkipList {
|
|||||||
curLevel.killInstance();
|
curLevel.killInstance();
|
||||||
curLevel = nextLevel;
|
curLevel = nextLevel;
|
||||||
}
|
}
|
||||||
stack.killInstance();
|
|
||||||
|
|
||||||
SkipSpan curSpan = first;
|
SkipSpan curSpan = first;
|
||||||
while(curSpan != null) {
|
while(curSpan != null) {
|
||||||
@@ -197,33 +200,36 @@ public class BSkipList extends SkipList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipIterator iterator() {
|
public SkipIterator<K, V> iterator() {
|
||||||
if (!this.fileOnly)
|
if (!this.fileOnly)
|
||||||
return super.iterator();
|
return super.iterator();
|
||||||
return new IBSkipIterator(first, 0);
|
return new IBSkipIterator<K, V>(first, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/****
|
||||||
public SkipIterator min() {
|
//@Override
|
||||||
|
public SkipIterator<K, V> min() {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//@Override
|
||||||
public SkipIterator max() {
|
public SkipIterator<K, V> max() {
|
||||||
if (!this.fileOnly)
|
if (!this.fileOnly)
|
||||||
return super.max();
|
return super.max();
|
||||||
SkipSpan ss = stack.getEnd();
|
SkipSpan<K, V> ss = stack.getEnd();
|
||||||
return new IBSkipIterator(ss, ss.nKeys - 1);
|
return new IBSkipIterator<K, V>(ss, ss.nKeys - 1);
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
|
|
||||||
|
/** find */
|
||||||
@Override
|
@Override
|
||||||
public SkipIterator find(Comparable key) {
|
public SkipIterator<K, V> find(K key) {
|
||||||
if (!this.fileOnly)
|
if (!this.fileOnly)
|
||||||
return super.find(key);
|
return super.find(key);
|
||||||
int[] search = new int[1];
|
int[] search = new int[1];
|
||||||
SkipSpan ss = stack.getSpan(stack.levels.length - 1, key, search);
|
SkipSpan<K, V> ss = stack.getSpan(stack.levels.length - 1, key, search);
|
||||||
if(search[0] < 0) { search[0] = -1 * (search[0] + 1); }
|
if(search[0] < 0) { search[0] = -1 * (search[0] + 1); }
|
||||||
return new IBSkipIterator(ss, search[0]);
|
return new IBSkipIterator<K, V>(ss, search[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,19 +59,19 @@ import net.i2p.util.Log;
|
|||||||
* next overflow page (unsigned int)
|
* next overflow page (unsigned int)
|
||||||
*</pre>
|
*</pre>
|
||||||
*/
|
*/
|
||||||
public class BSkipSpan extends SkipSpan {
|
public class BSkipSpan<K extends Comparable<? super K>, V> extends SkipSpan<K, V> {
|
||||||
protected static final int MAGIC = 0x5370616e; // "Span"
|
protected static final int MAGIC = 0x5370616e; // "Span"
|
||||||
protected static final int HEADER_LEN = 20;
|
protected static final int HEADER_LEN = 20;
|
||||||
public static final int CONT_HEADER_LEN = 8;
|
public static final int CONT_HEADER_LEN = 8;
|
||||||
protected final BlockFile bf;
|
protected final BlockFile bf;
|
||||||
private final BSkipList bsl;
|
private final BSkipList<K, V> bsl;
|
||||||
protected int page;
|
protected int page;
|
||||||
protected int overflowPage;
|
protected int overflowPage;
|
||||||
|
|
||||||
protected int prevPage;
|
protected int prevPage;
|
||||||
protected int nextPage;
|
protected int nextPage = 0;
|
||||||
protected Serializer keySer;
|
protected Serializer<K> keySer;
|
||||||
protected Serializer valSer;
|
protected Serializer<V> valSer;
|
||||||
|
|
||||||
// I2P
|
// I2P
|
||||||
protected int spanSize;
|
protected int spanSize;
|
||||||
@@ -88,11 +88,11 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipSpan newInstance(SkipList sl) {
|
public SkipSpan<K, V> newInstance(SkipList<K, V> sl) {
|
||||||
try {
|
try {
|
||||||
int newPage = bf.allocPage();
|
int newPage = bf.allocPage();
|
||||||
init(bf, newPage, bf.spanSize);
|
init(bf, newPage, bf.spanSize);
|
||||||
return new BSkipSpan(bf, (BSkipList) sl, newPage, keySer, valSer);
|
return new BSkipSpan<K, V>(bf, (BSkipList<K, V>) sl, newPage, keySer, valSer);
|
||||||
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +237,8 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
//bsl.flush();
|
//bsl.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void load(BSkipSpan bss, BlockFile bf, BSkipList bsl, int spanPage, Serializer key, Serializer val) throws IOException {
|
private static <X extends Comparable<? super X>, Y> void load(BSkipSpan<X, Y> bss, BlockFile bf, BSkipList<X, Y> bsl,
|
||||||
|
int spanPage, Serializer<X> key, Serializer<Y> val) throws IOException {
|
||||||
loadInit(bss, bf, bsl, spanPage, key, val);
|
loadInit(bss, bf, bsl, spanPage, key, val);
|
||||||
bss.loadData();
|
bss.loadData();
|
||||||
}
|
}
|
||||||
@@ -246,7 +247,8 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
* I2P - first half of load()
|
* I2P - first half of load()
|
||||||
* Only read the span headers
|
* Only read the span headers
|
||||||
*/
|
*/
|
||||||
protected static void loadInit(BSkipSpan bss, BlockFile bf, BSkipList bsl, int spanPage, Serializer key, Serializer val) throws IOException {
|
protected static <X extends Comparable<? super X>, Y> void loadInit(BSkipSpan<X, Y> bss, BlockFile bf, BSkipList<X, Y> bsl,
|
||||||
|
int spanPage, Serializer<X> key, Serializer<Y> val) throws IOException {
|
||||||
if (bss.isKilled)
|
if (bss.isKilled)
|
||||||
throw new IOException("Already killed!! " + bss);
|
throw new IOException("Already killed!! " + bss);
|
||||||
bss.page = spanPage;
|
bss.page = spanPage;
|
||||||
@@ -285,11 +287,12 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
* Load the whole span's keys and values into memory
|
* Load the whole span's keys and values into memory
|
||||||
* @param flushOnError set to false if you are going to flush anyway
|
* @param flushOnError set to false if you are going to flush anyway
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
protected void loadData(boolean flushOnError) throws IOException {
|
protected void loadData(boolean flushOnError) throws IOException {
|
||||||
if (isKilled)
|
if (isKilled)
|
||||||
throw new IOException("Already killed!! " + this);
|
throw new IOException("Already killed!! " + this);
|
||||||
this.keys = new Comparable[this.spanSize];
|
this.keys = (K[]) new Comparable[this.spanSize];
|
||||||
this.vals = new Object[this.spanSize];
|
this.vals = (V[]) new Object[this.spanSize];
|
||||||
|
|
||||||
int ksz, vsz;
|
int ksz, vsz;
|
||||||
int curPage = this.page;
|
int curPage = this.page;
|
||||||
@@ -327,7 +330,7 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// System.out.println("i=" + i + ", Page " + curPage + ", offset " + pageCounter[0] + " ksz " + ksz + " vsz " + vsz);
|
// System.out.println("i=" + i + ", Page " + curPage + ", offset " + pageCounter[0] + " ksz " + ksz + " vsz " + vsz);
|
||||||
this.keys[i] = (Comparable) this.keySer.construct(k);
|
this.keys[i] = this.keySer.construct(k);
|
||||||
this.vals[i] = this.valSer.construct(v);
|
this.vals[i] = this.valSer.construct(v);
|
||||||
// Drop bad entry without throwing exception
|
// Drop bad entry without throwing exception
|
||||||
if (this.keys[i] == null || this.vals[i] == null) {
|
if (this.keys[i] == null || this.vals[i] == null) {
|
||||||
@@ -377,31 +380,31 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BSkipSpan(BlockFile bf, BSkipList bsl) {
|
protected BSkipSpan(BlockFile bf, BSkipList<K, V> bsl) {
|
||||||
this.bf = bf;
|
this.bf = bf;
|
||||||
this.bsl = bsl;
|
this.bsl = bsl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BSkipSpan(BlockFile bf, BSkipList bsl, int spanPage, Serializer key, Serializer val) throws IOException {
|
public BSkipSpan(BlockFile bf, BSkipList<K, V> bsl, int spanPage, Serializer<K> key, Serializer<V> val) throws IOException {
|
||||||
this.bf = bf;
|
this.bf = bf;
|
||||||
this.bsl = bsl;
|
this.bsl = bsl;
|
||||||
BSkipSpan.load(this, bf, bsl, spanPage, key, val);
|
BSkipSpan.load(this, bf, bsl, spanPage, key, val);
|
||||||
this.next = null;
|
this.next = null;
|
||||||
this.prev = null;
|
this.prev = null;
|
||||||
|
|
||||||
BSkipSpan bss = this;
|
BSkipSpan<K, V> bss = this;
|
||||||
// findbugs ok (set in load() above)
|
// findbugs ok (set in load() above)
|
||||||
int np = nextPage;
|
int np = nextPage;
|
||||||
while(np != 0) {
|
while(np != 0) {
|
||||||
BSkipSpan temp = bsl.spanHash.get(Integer.valueOf(np));
|
BSkipSpan<K, V> temp = bsl.spanHash.get(Integer.valueOf(np));
|
||||||
if(temp != null) {
|
if(temp != null) {
|
||||||
bss.next = temp;
|
bss.next = temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bss.next = new BSkipSpan(bf, bsl);
|
bss.next = new BSkipSpan<K, V>(bf, bsl);
|
||||||
bss.next.next = null;
|
bss.next.next = null;
|
||||||
bss.next.prev = bss;
|
bss.next.prev = bss;
|
||||||
bss = (BSkipSpan) bss.next;
|
bss = (BSkipSpan<K, V>) bss.next;
|
||||||
|
|
||||||
BSkipSpan.load(bss, bf, bsl, np, key, val);
|
BSkipSpan.load(bss, bf, bsl, np, key, val);
|
||||||
np = bss.nextPage;
|
np = bss.nextPage;
|
||||||
@@ -411,15 +414,15 @@ public class BSkipSpan extends SkipSpan {
|
|||||||
bss = this;
|
bss = this;
|
||||||
np = prevPage;
|
np = prevPage;
|
||||||
while(np != 0) {
|
while(np != 0) {
|
||||||
BSkipSpan temp = bsl.spanHash.get(Integer.valueOf(np));
|
BSkipSpan<K, V> temp = bsl.spanHash.get(Integer.valueOf(np));
|
||||||
if(temp != null) {
|
if(temp != null) {
|
||||||
bss.prev = temp;
|
bss.prev = temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bss.prev = new BSkipSpan(bf, bsl);
|
bss.prev = new BSkipSpan<K, V>(bf, bsl);
|
||||||
bss.prev.next = bss;
|
bss.prev.next = bss;
|
||||||
bss.prev.prev = null;
|
bss.prev.prev = null;
|
||||||
bss = (BSkipSpan) bss.prev;
|
bss = (BSkipSpan<K, V>) bss.prev;
|
||||||
|
|
||||||
BSkipSpan.load(bss, bf, bsl, np, key, val);
|
BSkipSpan.load(bss, bf, bsl, np, key, val);
|
||||||
np = bss.prevPage;
|
np = bss.prevPage;
|
||||||
@@ -41,9 +41,9 @@ import net.metanotion.util.skiplist.SkipSpan;
|
|||||||
If the caller does not iterate all the way through, the last span
|
If the caller does not iterate all the way through, the last span
|
||||||
will remain in memory.
|
will remain in memory.
|
||||||
*/
|
*/
|
||||||
public class IBSkipIterator extends SkipIterator {
|
public class IBSkipIterator<K extends Comparable<? super K>, V> extends SkipIterator<K, V> {
|
||||||
|
|
||||||
public IBSkipIterator(SkipSpan ss, int index) {
|
public IBSkipIterator(SkipSpan<K, V> ss, int index) {
|
||||||
super(ss, index);
|
super(ss, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ public class IBSkipIterator extends SkipIterator {
|
|||||||
* @throws RuntimeException on IOE
|
* @throws RuntimeException on IOE
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object next() {
|
public V next() {
|
||||||
Object o;
|
V o;
|
||||||
if(index < ss.nKeys) {
|
if(index < ss.nKeys) {
|
||||||
if (ss.vals == null) {
|
if (ss.vals == null) {
|
||||||
try {
|
try {
|
||||||
@@ -90,7 +90,7 @@ public class IBSkipIterator extends SkipIterator {
|
|||||||
* @throws RuntimeException on IOE
|
* @throws RuntimeException on IOE
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Comparable nextKey() {
|
public K nextKey() {
|
||||||
if(index < ss.nKeys) {
|
if(index < ss.nKeys) {
|
||||||
if (ss.keys == null) {
|
if (ss.keys == null) {
|
||||||
try {
|
try {
|
||||||
@@ -110,7 +110,7 @@ public class IBSkipIterator extends SkipIterator {
|
|||||||
* @throws RuntimeException on IOE
|
* @throws RuntimeException on IOE
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object previous() {
|
public V previous() {
|
||||||
if(index > 0) {
|
if(index > 0) {
|
||||||
index--;
|
index--;
|
||||||
} else if(ss.prev != null) {
|
} else if(ss.prev != null) {
|
||||||
@@ -54,21 +54,22 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
* @author zzz
|
* @author zzz
|
||||||
*/
|
*/
|
||||||
public class IBSkipSpan extends BSkipSpan {
|
public class IBSkipSpan<K extends Comparable<? super K>, V> extends BSkipSpan<K, V> {
|
||||||
|
|
||||||
private Comparable firstKey;
|
private K firstKey;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipSpan newInstance(SkipList sl) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public SkipSpan<K, V> newInstance(SkipList<K, V> sl) {
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Splitting page " + this.page + " containing " + this.nKeys + '/' + this.spanSize);
|
bf.log.debug("Splitting page " + this.page + " containing " + this.nKeys + '/' + this.spanSize);
|
||||||
try {
|
try {
|
||||||
int newPage = bf.allocPage();
|
int newPage = bf.allocPage();
|
||||||
init(bf, newPage, bf.spanSize);
|
init(bf, newPage, bf.spanSize);
|
||||||
SkipSpan rv = new IBSkipSpan(bf, (BSkipList) sl, newPage, keySer, valSer);
|
SkipSpan<K, V> rv = new IBSkipSpan<K, V>(bf, (BSkipList<K, V>) sl, newPage, keySer, valSer);
|
||||||
// this is called after a split, so we need the data arrays initialized
|
// this is called after a split, so we need the data arrays initialized
|
||||||
rv.keys = new Comparable[bf.spanSize];
|
rv.keys = (K[]) new Comparable[bf.spanSize];
|
||||||
rv.vals = new Object[bf.spanSize];
|
rv.vals = (V[]) new Object[bf.spanSize];
|
||||||
return rv;
|
return rv;
|
||||||
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
} catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); }
|
||||||
}
|
}
|
||||||
@@ -125,7 +126,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
pageCounter[0] +=4;
|
pageCounter[0] +=4;
|
||||||
byte[] k = new byte[ksz];
|
byte[] k = new byte[ksz];
|
||||||
curPage = this.bf.readMultiPageData(k, curPage, pageCounter, curNextPage);
|
curPage = this.bf.readMultiPageData(k, curPage, pageCounter, curNextPage);
|
||||||
this.firstKey = (Comparable) this.keySer.construct(k);
|
this.firstKey = this.keySer.construct(k);
|
||||||
if (this.firstKey == null) {
|
if (this.firstKey == null) {
|
||||||
bf.log.error("Null deserialized first key in page " + curPage);
|
bf.log.error("Null deserialized first key in page " + curPage);
|
||||||
repair(1);
|
repair(1);
|
||||||
@@ -160,7 +161,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
/**
|
/**
|
||||||
* Linear search through the span in the file for the value.
|
* Linear search through the span in the file for the value.
|
||||||
*/
|
*/
|
||||||
private Object getData(Comparable key) throws IOException {
|
private V getData(K key) throws IOException {
|
||||||
seekData();
|
seekData();
|
||||||
int curPage = this.page;
|
int curPage = this.page;
|
||||||
int[] curNextPage = new int[1];
|
int[] curNextPage = new int[1];
|
||||||
@@ -194,7 +195,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//System.out.println("i=" + i + ", Page " + curPage + ", offset " + pageCounter[0] + " ksz " + ksz + " vsz " + vsz);
|
//System.out.println("i=" + i + ", Page " + curPage + ", offset " + pageCounter[0] + " ksz " + ksz + " vsz " + vsz);
|
||||||
Comparable ckey = (Comparable) this.keySer.construct(k);
|
K ckey = this.keySer.construct(k);
|
||||||
if (ckey == null) {
|
if (ckey == null) {
|
||||||
// skip the value and keep going
|
// skip the value and keep going
|
||||||
curPage = this.bf.skipMultiPageBytes(vsz, curPage, pageCounter, curNextPage);
|
curPage = this.bf.skipMultiPageBytes(vsz, curPage, pageCounter, curNextPage);
|
||||||
@@ -213,7 +214,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
lostEntries(i, curPage);
|
lostEntries(i, curPage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Object rv = this.valSer.construct(v);
|
V rv = this.valSer.construct(v);
|
||||||
if (rv == null) {
|
if (rv == null) {
|
||||||
bf.log.error("Null deserialized value in entry " + i + " page " + curPage +
|
bf.log.error("Null deserialized value in entry " + i + " page " + curPage +
|
||||||
" key=" + ckey);
|
" key=" + ckey);
|
||||||
@@ -252,11 +253,11 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
*****/
|
*****/
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBSkipSpan(BlockFile bf, BSkipList bsl) {
|
private IBSkipSpan(BlockFile bf, BSkipList<K, V> bsl) {
|
||||||
super(bf, bsl);
|
super(bf, bsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBSkipSpan(BlockFile bf, BSkipList bsl, int spanPage, Serializer key, Serializer val) throws IOException {
|
public IBSkipSpan(BlockFile bf, BSkipList<K, V> bsl, int spanPage, Serializer<K> key, Serializer<V> val) throws IOException {
|
||||||
super(bf, bsl);
|
super(bf, bsl);
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("New ibss page " + spanPage);
|
bf.log.debug("New ibss page " + spanPage);
|
||||||
@@ -265,24 +266,24 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
this.next = null;
|
this.next = null;
|
||||||
this.prev = null;
|
this.prev = null;
|
||||||
|
|
||||||
IBSkipSpan bss = this;
|
IBSkipSpan<K, V> bss = this;
|
||||||
IBSkipSpan temp;
|
IBSkipSpan<K, V> temp;
|
||||||
int np = nextPage;
|
int np = nextPage;
|
||||||
while(np != 0) {
|
while(np != 0) {
|
||||||
temp = (IBSkipSpan) bsl.spanHash.get(Integer.valueOf(np));
|
temp = (IBSkipSpan<K, V>) bsl.spanHash.get(Integer.valueOf(np));
|
||||||
if(temp != null) {
|
if(temp != null) {
|
||||||
bss.next = temp;
|
bss.next = temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bss.next = new IBSkipSpan(bf, bsl);
|
bss.next = new IBSkipSpan<K, V>(bf, bsl);
|
||||||
bss.next.next = null;
|
bss.next.next = null;
|
||||||
bss.next.prev = bss;
|
bss.next.prev = bss;
|
||||||
Comparable previousFirstKey = bss.firstKey;
|
K previousFirstKey = bss.firstKey;
|
||||||
bss = (IBSkipSpan) bss.next;
|
bss = (IBSkipSpan<K, V>) bss.next;
|
||||||
|
|
||||||
BSkipSpan.loadInit(bss, bf, bsl, np, key, val);
|
BSkipSpan.loadInit(bss, bf, bsl, np, key, val);
|
||||||
bss.loadFirstKey();
|
bss.loadFirstKey();
|
||||||
Comparable nextFirstKey = bss.firstKey;
|
K nextFirstKey = bss.firstKey;
|
||||||
if (previousFirstKey == null || nextFirstKey == null ||
|
if (previousFirstKey == null || nextFirstKey == null ||
|
||||||
previousFirstKey.compareTo(nextFirstKey) >= 0) {
|
previousFirstKey.compareTo(nextFirstKey) >= 0) {
|
||||||
// TODO remove, but if we are at the bottom of a level
|
// TODO remove, but if we are at the bottom of a level
|
||||||
@@ -299,20 +300,20 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
bss = this;
|
bss = this;
|
||||||
np = prevPage;
|
np = prevPage;
|
||||||
while(np != 0) {
|
while(np != 0) {
|
||||||
temp = (IBSkipSpan) bsl.spanHash.get(Integer.valueOf(np));
|
temp = (IBSkipSpan<K, V>) bsl.spanHash.get(Integer.valueOf(np));
|
||||||
if(temp != null) {
|
if(temp != null) {
|
||||||
bss.prev = temp;
|
bss.prev = temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bss.prev = new IBSkipSpan(bf, bsl);
|
bss.prev = new IBSkipSpan<K, V>(bf, bsl);
|
||||||
bss.prev.next = bss;
|
bss.prev.next = bss;
|
||||||
bss.prev.prev = null;
|
bss.prev.prev = null;
|
||||||
Comparable nextFirstKey = bss.firstKey;
|
K nextFirstKey = bss.firstKey;
|
||||||
bss = (IBSkipSpan) bss.prev;
|
bss = (IBSkipSpan<K, V>) bss.prev;
|
||||||
|
|
||||||
BSkipSpan.loadInit(bss, bf, bsl, np, key, val);
|
BSkipSpan.loadInit(bss, bf, bsl, np, key, val);
|
||||||
bss.loadFirstKey();
|
bss.loadFirstKey();
|
||||||
Comparable previousFirstKey = bss.firstKey;
|
K previousFirstKey = bss.firstKey;
|
||||||
if (previousFirstKey == null || nextFirstKey == null ||
|
if (previousFirstKey == null || nextFirstKey == null ||
|
||||||
previousFirstKey.compareTo(nextFirstKey) >= 0) {
|
previousFirstKey.compareTo(nextFirstKey) >= 0) {
|
||||||
// TODO remove, but if we are at the bottom of a level
|
// TODO remove, but if we are at the bottom of a level
|
||||||
@@ -330,7 +331,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
* Does not call super, we always store first key here
|
* Does not call super, we always store first key here
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Comparable firstKey() {
|
public K firstKey() {
|
||||||
return this.firstKey;
|
return this.firstKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,13 +340,13 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
* This is called only via SkipList.find()
|
* This is called only via SkipList.find()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SkipSpan getSpan(Comparable key, int[] search) {
|
public SkipSpan<K, V> getSpan(K key, int[] search) {
|
||||||
try {
|
try {
|
||||||
seekAndLoadData();
|
seekAndLoadData();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new RuntimeException("Error reading database", ioe);
|
throw new RuntimeException("Error reading database", ioe);
|
||||||
}
|
}
|
||||||
SkipSpan rv = super.getSpan(key, search);
|
SkipSpan<K, V> rv = super.getSpan(key, search);
|
||||||
this.keys = null;
|
this.keys = null;
|
||||||
this.vals = null;
|
this.vals = null;
|
||||||
return rv;
|
return rv;
|
||||||
@@ -355,7 +356,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
* Linear search if in file, Binary search if in memory
|
* Linear search if in file, Binary search if in memory
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object get(Comparable key) {
|
public V get(K key) {
|
||||||
try {
|
try {
|
||||||
if (nKeys == 0) { return null; }
|
if (nKeys == 0) { return null; }
|
||||||
if (this.next != null && this.next.firstKey().compareTo(key) <= 0)
|
if (this.next != null && this.next.firstKey().compareTo(key) <= 0)
|
||||||
@@ -370,13 +371,13 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
* Load whole span from file, do the operation, flush out, then null out in-memory data again.
|
* Load whole span from file, do the operation, flush out, then null out in-memory data again.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SkipSpan put(Comparable key, Object val, SkipList sl) {
|
public SkipSpan<K, V> put(K key, V val, SkipList<K, V> sl) {
|
||||||
try {
|
try {
|
||||||
seekAndLoadData();
|
seekAndLoadData();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new RuntimeException("Error reading database", ioe);
|
throw new RuntimeException("Error reading database", ioe);
|
||||||
}
|
}
|
||||||
SkipSpan rv = super.put(key, val, sl);
|
SkipSpan<K, V> rv = super.put(key, val, sl);
|
||||||
// flush() nulls out the data
|
// flush() nulls out the data
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -385,7 +386,7 @@ public class IBSkipSpan extends BSkipSpan {
|
|||||||
* Load whole span from file, do the operation, flush out, then null out in-memory data again.
|
* Load whole span from file, do the operation, flush out, then null out in-memory data again.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object[] remove(Comparable key, SkipList sl) {
|
public Object[] remove(K key, SkipList<K, V> sl) {
|
||||||
if (bf.log.shouldLog(Log.DEBUG))
|
if (bf.log.shouldLog(Log.DEBUG))
|
||||||
bf.log.debug("Remove " + key + " in " + this);
|
bf.log.debug("Remove " + key + " in " + this);
|
||||||
if (nKeys <= 0)
|
if (nKeys <= 0)
|
||||||
@@ -35,11 +35,11 @@ import net.metanotion.io.Serializer;
|
|||||||
* Will never return null.
|
* Will never return null.
|
||||||
* Added by I2P.
|
* Added by I2P.
|
||||||
*/
|
*/
|
||||||
public class IdentityBytes implements Serializer {
|
public class IdentityBytes implements Serializer<byte[]> {
|
||||||
|
|
||||||
/** @return byte[] */
|
/** @return byte[] */
|
||||||
public byte[] getBytes(Object o) { return (byte[])o; }
|
public byte[] getBytes(byte[] o) { return o; }
|
||||||
|
|
||||||
/** @return b */
|
/** @return b */
|
||||||
public Object construct(byte[] b) { return b; }
|
public byte[] construct(byte[] b) { return b; }
|
||||||
}
|
}
|
||||||
@@ -30,10 +30,10 @@ package net.metanotion.io.data;
|
|||||||
|
|
||||||
import net.metanotion.io.Serializer;
|
import net.metanotion.io.Serializer;
|
||||||
|
|
||||||
public class IntBytes implements Serializer {
|
public class IntBytes implements Serializer<Integer> {
|
||||||
public byte[] getBytes(Object o) {
|
public byte[] getBytes(Integer o) {
|
||||||
byte[] b = new byte[4];
|
byte[] b = new byte[4];
|
||||||
int v = ((Integer) o).intValue();
|
int v = o.intValue();
|
||||||
b[0] = (byte)(0xff & (v >> 24));
|
b[0] = (byte)(0xff & (v >> 24));
|
||||||
b[1] = (byte)(0xff & (v >> 16));
|
b[1] = (byte)(0xff & (v >> 16));
|
||||||
b[2] = (byte)(0xff & (v >> 8));
|
b[2] = (byte)(0xff & (v >> 8));
|
||||||
@@ -41,7 +41,7 @@ public class IntBytes implements Serializer {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object construct(byte[] b) {
|
public Integer construct(byte[] b) {
|
||||||
int v = (((b[0] & 0xff) << 24) |
|
int v = (((b[0] & 0xff) << 24) |
|
||||||
((b[1] & 0xff) << 16) |
|
((b[1] & 0xff) << 16) |
|
||||||
((b[2] & 0xff) << 8) |
|
((b[2] & 0xff) << 8) |
|
||||||
@@ -32,14 +32,14 @@ import java.io.UnsupportedEncodingException;
|
|||||||
|
|
||||||
import net.metanotion.io.Serializer;
|
import net.metanotion.io.Serializer;
|
||||||
|
|
||||||
public class StringBytes implements Serializer {
|
public class StringBytes implements Serializer<String> {
|
||||||
public byte[] getBytes(Object o) {
|
public byte[] getBytes(String o) {
|
||||||
try {
|
try {
|
||||||
return ((String) o).getBytes("US-ASCII");
|
return o.getBytes("US-ASCII");
|
||||||
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object construct(byte[] b) {
|
public String construct(byte[] b) {
|
||||||
try {
|
try {
|
||||||
return new String(b, "US-ASCII");
|
return new String(b, "US-ASCII");
|
||||||
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
||||||
@@ -35,14 +35,14 @@ import net.metanotion.io.Serializer;
|
|||||||
/**
|
/**
|
||||||
* Added by I2P
|
* Added by I2P
|
||||||
*/
|
*/
|
||||||
public class UTF8StringBytes implements Serializer {
|
public class UTF8StringBytes implements Serializer<String> {
|
||||||
public byte[] getBytes(Object o) {
|
public byte[] getBytes(String o) {
|
||||||
try {
|
try {
|
||||||
return ((String) o).getBytes("UTF-8");
|
return o.getBytes("UTF-8");
|
||||||
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object construct(byte[] b) {
|
public String construct(byte[] b) {
|
||||||
try {
|
try {
|
||||||
return new String(b, "UTF-8");
|
return new String(b, "UTF-8");
|
||||||
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
} catch (UnsupportedEncodingException uee) { throw new Error("Unsupported Encoding"); }
|
||||||
@@ -39,12 +39,13 @@ import java.util.NoSuchElementException;
|
|||||||
To be clear, this is an iterator through the values.
|
To be clear, this is an iterator through the values.
|
||||||
To get the key, call nextKey() BEFORE calling next().
|
To get the key, call nextKey() BEFORE calling next().
|
||||||
*/
|
*/
|
||||||
public class SkipIterator implements ListIterator {
|
public class SkipIterator<K extends Comparable<? super K>, V> implements ListIterator<V> {
|
||||||
protected SkipSpan ss;
|
protected SkipSpan<K, V> ss;
|
||||||
protected int index;
|
protected int index;
|
||||||
|
|
||||||
protected SkipIterator() { }
|
protected SkipIterator() { }
|
||||||
public SkipIterator(SkipSpan ss, int index) {
|
|
||||||
|
public SkipIterator(SkipSpan<K, V> ss, int index) {
|
||||||
if(ss==null) { throw new NullPointerException(); }
|
if(ss==null) { throw new NullPointerException(); }
|
||||||
this.ss = ss;
|
this.ss = ss;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
@@ -59,8 +60,8 @@ public class SkipIterator implements ListIterator {
|
|||||||
* @return the next value, and advances the index
|
* @return the next value, and advances the index
|
||||||
* @throws NoSuchElementException
|
* @throws NoSuchElementException
|
||||||
*/
|
*/
|
||||||
public Object next() {
|
public V next() {
|
||||||
Object o;
|
V o;
|
||||||
if(index < ss.nKeys) {
|
if(index < ss.nKeys) {
|
||||||
o = ss.vals[index];
|
o = ss.vals[index];
|
||||||
} else {
|
} else {
|
||||||
@@ -83,7 +84,7 @@ public class SkipIterator implements ListIterator {
|
|||||||
* @return the key for which the value will be returned in the subsequent call to next()
|
* @return the key for which the value will be returned in the subsequent call to next()
|
||||||
* @throws NoSuchElementException
|
* @throws NoSuchElementException
|
||||||
*/
|
*/
|
||||||
public Comparable nextKey() {
|
public K nextKey() {
|
||||||
if(index < ss.nKeys) { return ss.keys[index]; }
|
if(index < ss.nKeys) { return ss.keys[index]; }
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,7 @@ public class SkipIterator implements ListIterator {
|
|||||||
* @return the previous value, and decrements the index
|
* @return the previous value, and decrements the index
|
||||||
* @throws NoSuchElementException
|
* @throws NoSuchElementException
|
||||||
*/
|
*/
|
||||||
public Object previous() {
|
public V previous() {
|
||||||
if(index > 0) {
|
if(index > 0) {
|
||||||
index--;
|
index--;
|
||||||
} else if(ss.prev != null) {
|
} else if(ss.prev != null) {
|
||||||
@@ -111,9 +112,9 @@ public class SkipIterator implements ListIterator {
|
|||||||
|
|
||||||
|
|
||||||
// Optional methods
|
// Optional methods
|
||||||
public void add(Object o) { throw new UnsupportedOperationException(); }
|
public void add(V o) { throw new UnsupportedOperationException(); }
|
||||||
public void remove() { throw new UnsupportedOperationException(); }
|
public void remove() { throw new UnsupportedOperationException(); }
|
||||||
public void set(Object o) { throw new UnsupportedOperationException(); }
|
public void set(V o) { throw new UnsupportedOperationException(); }
|
||||||
public int nextIndex() { throw new UnsupportedOperationException(); }
|
public int nextIndex() { throw new UnsupportedOperationException(); }
|
||||||
public int previousIndex() { throw new UnsupportedOperationException(); }
|
public int previousIndex() { throw new UnsupportedOperationException(); }
|
||||||
|
|
||||||
@@ -28,12 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.util.skiplist;
|
package net.metanotion.util.skiplist;
|
||||||
|
|
||||||
|
import java.io.Flushable;
|
||||||
|
|
||||||
import net.metanotion.io.block.BlockFile;
|
import net.metanotion.io.block.BlockFile;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
public class SkipLevels {
|
public class SkipLevels<K extends Comparable<? super K>, V> implements Flushable {
|
||||||
/** We can't have more than 2**32 pages */
|
/** We can't have more than 2**32 pages */
|
||||||
public static final int MAX_SIZE = 32;
|
public static final int MAX_SIZE = 32;
|
||||||
|
|
||||||
@@ -43,12 +45,15 @@ public class SkipLevels {
|
|||||||
* The "bottom" level is the direct pointer to a SkipSpan.
|
* The "bottom" level is the direct pointer to a SkipSpan.
|
||||||
*/
|
*/
|
||||||
// levels is almost final
|
// levels is almost final
|
||||||
public SkipLevels[] levels;
|
public SkipLevels<K, V>[] levels;
|
||||||
// bottom is final
|
// bottom is final
|
||||||
public SkipSpan bottom;
|
public SkipSpan<K, V> bottom;
|
||||||
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(BlockFile.class);
|
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(BlockFile.class);
|
||||||
|
|
||||||
public SkipLevels newInstance(int levels, SkipSpan ss, SkipList sl) { return new SkipLevels(levels, ss); }
|
public SkipLevels<K, V> newInstance(int levels, SkipSpan<K, V> ss, SkipList<K, V> sl) {
|
||||||
|
return new SkipLevels<K, V>(levels, ss);
|
||||||
|
}
|
||||||
|
|
||||||
public void killInstance() { }
|
public void killInstance() { }
|
||||||
public void flush() { }
|
public void flush() { }
|
||||||
|
|
||||||
@@ -57,10 +62,11 @@ public class SkipLevels {
|
|||||||
/*
|
/*
|
||||||
* @throws IllegalArgumentException if size too big or too small
|
* @throws IllegalArgumentException if size too big or too small
|
||||||
*/
|
*/
|
||||||
public SkipLevels(int size, SkipSpan span) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public SkipLevels(int size, SkipSpan<K, V> span) {
|
||||||
if(size < 1 || size > MAX_SIZE)
|
if(size < 1 || size > MAX_SIZE)
|
||||||
throw new IllegalArgumentException("Invalid Level Skip size");
|
throw new IllegalArgumentException("Invalid Level Skip size");
|
||||||
levels = new SkipLevels[size];
|
levels = (SkipLevels<K, V>[]) new SkipLevels[size];
|
||||||
bottom = span;
|
bottom = span;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,14 +96,14 @@ public class SkipLevels {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkipSpan getEnd() {
|
public SkipSpan<K, V> getEnd() {
|
||||||
for(int i=(levels.length - 1);i>=0;i--) {
|
for(int i=(levels.length - 1);i>=0;i--) {
|
||||||
if(levels[i] != null) { return levels[i].getEnd(); }
|
if(levels[i] != null) { return levels[i].getEnd(); }
|
||||||
}
|
}
|
||||||
return bottom.getEnd();
|
return bottom.getEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkipSpan getSpan(int start, Comparable key, int[] search) {
|
public SkipSpan<K, V> getSpan(int start, K key, int[] search) {
|
||||||
for(int i=Math.min(start, levels.length - 1);i>=0;i--) {
|
for(int i=Math.min(start, levels.length - 1);i>=0;i--) {
|
||||||
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
||||||
return levels[i].getSpan(i,key,search);
|
return levels[i].getSpan(i,key,search);
|
||||||
@@ -106,9 +112,9 @@ public class SkipLevels {
|
|||||||
return bottom.getSpan(key, search);
|
return bottom.getSpan(key, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Comparable key() { return bottom.firstKey(); }
|
public K key() { return bottom.firstKey(); }
|
||||||
|
|
||||||
public Object get(int start, Comparable key) {
|
public V get(int start, K key) {
|
||||||
for(int i=Math.min(start, levels.length - 1);i>=0;i--) {
|
for(int i=Math.min(start, levels.length - 1);i>=0;i--) {
|
||||||
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
||||||
return levels[i].get(i,key);
|
return levels[i].get(i,key);
|
||||||
@@ -124,16 +130,17 @@ public class SkipLevels {
|
|||||||
* and the deleted SkipLevels is taller than this SkipLevels.
|
* and the deleted SkipLevels is taller than this SkipLevels.
|
||||||
* rv is null if no object was removed.
|
* rv is null if no object was removed.
|
||||||
*/
|
*/
|
||||||
public Object[] remove(int start, Comparable key, SkipList sl) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object[] remove(int start, K key, SkipList<K, V> sl) {
|
||||||
Object[] res = null;
|
Object[] res = null;
|
||||||
SkipLevels slvls = null;
|
SkipLevels<K, V> slvls = null;
|
||||||
for(int i = Math.min(start, levels.length - 1); i >= 0; i--) {
|
for(int i = Math.min(start, levels.length - 1); i >= 0; i--) {
|
||||||
if(levels[i] != null) {
|
if(levels[i] != null) {
|
||||||
int cmp = levels[i].key().compareTo(key);
|
int cmp = levels[i].key().compareTo(key);
|
||||||
if((cmp < 0) || ((i==0) && (cmp <= 0))) {
|
if((cmp < 0) || ((i==0) && (cmp <= 0))) {
|
||||||
res = levels[i].remove(i, key, sl);
|
res = levels[i].remove(i, key, sl);
|
||||||
if((res != null) && (res[1] != null)) {
|
if((res != null) && (res[1] != null)) {
|
||||||
slvls = (SkipLevels) res[1];
|
slvls = (SkipLevels<K, V>) res[1];
|
||||||
if(levels.length >= slvls.levels.length) {
|
if(levels.length >= slvls.levels.length) {
|
||||||
res[1] = null;
|
res[1] = null;
|
||||||
}
|
}
|
||||||
@@ -157,7 +164,7 @@ public class SkipLevels {
|
|||||||
// if the returned SkipSpan was already copied to us
|
// if the returned SkipSpan was already copied to us
|
||||||
boolean isFirst = sl.first == bottom;
|
boolean isFirst = sl.first == bottom;
|
||||||
if (isFirst && levels[0] != null) {
|
if (isFirst && levels[0] != null) {
|
||||||
SkipSpan ssres = (SkipSpan)res[1];
|
SkipSpan<K, V> ssres = (SkipSpan<K, V>)res[1];
|
||||||
if (bottom.firstKey().equals(ssres.firstKey())) {
|
if (bottom.firstKey().equals(ssres.firstKey())) {
|
||||||
// bottom copied the next span to itself
|
// bottom copied the next span to itself
|
||||||
if (_log.shouldLog(Log.INFO)) {
|
if (_log.shouldLog(Log.INFO)) {
|
||||||
@@ -169,7 +176,7 @@ public class SkipLevels {
|
|||||||
_log.info("FIXUP TIME");
|
_log.info("FIXUP TIME");
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipLevels replace = levels[0];
|
SkipLevels<K, V> replace = levels[0];
|
||||||
for (int i = 0; i < levels.length; i++) {
|
for (int i = 0; i < levels.length; i++) {
|
||||||
if (levels[i] == null)
|
if (levels[i] == null)
|
||||||
break;
|
break;
|
||||||
@@ -195,11 +202,11 @@ public class SkipLevels {
|
|||||||
if((bottom.nKeys == 0) && (sl.first != bottom)) {
|
if((bottom.nKeys == 0) && (sl.first != bottom)) {
|
||||||
// from debugging other problems
|
// from debugging other problems
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
_log.warn("WTF killing with no return value " + print());
|
_log.warn("killing with no return value " + print());
|
||||||
} else if (res[1] == null) {
|
} else if (res[1] == null) {
|
||||||
_log.warn("WTF killing with no return value 1 " + print());
|
_log.warn("killing with no return value 1 " + print());
|
||||||
} else if (res[1] != this) {
|
} else if (res[1] != this) {
|
||||||
_log.warn("WTF killing with return value not us " + res[1] + ' ' + print());
|
_log.warn("killing with return value not us " + res[1] + ' ' + print());
|
||||||
}
|
}
|
||||||
this.killInstance();
|
this.killInstance();
|
||||||
}
|
}
|
||||||
@@ -211,12 +218,12 @@ public class SkipLevels {
|
|||||||
* and the new level is taller than our level;
|
* and the new level is taller than our level;
|
||||||
* else null if it went in an existing level or the new level is our height or less.
|
* else null if it went in an existing level or the new level is our height or less.
|
||||||
*/
|
*/
|
||||||
public SkipLevels put(int start, Comparable key, Object val, SkipList sl) {
|
public SkipLevels<K, V> put(int start, K key, V val, SkipList<K, V> sl) {
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for(int i = Math.min(start, levels.length - 1); i >= 0; i--) {
|
for(int i = Math.min(start, levels.length - 1); i >= 0; i--) {
|
||||||
// is key equal to or after the start of the level?
|
// is key equal to or after the start of the level?
|
||||||
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
if((levels[i] != null) && (levels[i].key().compareTo(key) <= 0)) {
|
||||||
SkipLevels slvls = levels[i].put(i, key, val, sl);
|
SkipLevels<K, V> slvls = levels[i].put(i, key, val, sl);
|
||||||
if(slvls != null) {
|
if(slvls != null) {
|
||||||
for (int j = i + 1; j < Math.min(slvls.levels.length, levels.length); j++) {
|
for (int j = i + 1; j < Math.min(slvls.levels.length, levels.length); j++) {
|
||||||
// he points to where we used to point
|
// he points to where we used to point
|
||||||
@@ -241,11 +248,11 @@ public class SkipLevels {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SkipSpan ss = bottom.put(key,val,sl);
|
SkipSpan<K, V> ss = bottom.put(key,val,sl);
|
||||||
if(ss!=null) {
|
if(ss!=null) {
|
||||||
int height = sl.generateColHeight();
|
int height = sl.generateColHeight();
|
||||||
if(height != 0) {
|
if(height != 0) {
|
||||||
SkipLevels slvls = this.newInstance(height, ss, sl);
|
SkipLevels<K, V> slvls = this.newInstance(height, ss, sl);
|
||||||
for(int i=0;i<(Math.min(height,levels.length));i++) {
|
for(int i=0;i<(Math.min(height,levels.length));i++) {
|
||||||
// he points to where we used to point
|
// he points to where we used to point
|
||||||
// and we now point to him
|
// and we now point to him
|
||||||
@@ -265,6 +272,6 @@ public class SkipLevels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean blvlck(boolean fix) { return false; }
|
public boolean blvlck(boolean fix) { return false; }
|
||||||
public boolean blvlck(boolean fix, int width, SkipLevels[] prevLevels) { return false; }
|
public boolean blvlck(boolean fix, int width, SkipLevels<K, V>[] prevLevels) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,19 +28,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.util.skiplist;
|
package net.metanotion.util.skiplist;
|
||||||
|
|
||||||
|
import java.io.Flushable;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.i2p.util.RandomSource;
|
import net.i2p.util.RandomSource;
|
||||||
|
|
||||||
//import net.metanotion.io.block.BlockFile;
|
//import net.metanotion.io.block.BlockFile;
|
||||||
|
|
||||||
public class SkipList {
|
public class SkipList<K extends Comparable<? super K>, V> implements Flushable, Iterable<V> {
|
||||||
/** the probability of each next higher level */
|
/** the probability of each next higher level */
|
||||||
protected static final int P = 2;
|
protected static final int P = 2;
|
||||||
private static final int MIN_SLOTS = 4;
|
private static final int MIN_SLOTS = 4;
|
||||||
// these two are really final
|
// these two are really final
|
||||||
protected SkipSpan first;
|
protected SkipSpan<K, V> first;
|
||||||
protected SkipLevels stack;
|
protected SkipLevels<K, V> stack;
|
||||||
// I2P mod
|
// I2P mod
|
||||||
public static final Random rng = RandomSource.getInstance();
|
public static final Random rng = RandomSource.getInstance();
|
||||||
|
|
||||||
@@ -56,8 +57,8 @@ public class SkipList {
|
|||||||
public SkipList(int span) {
|
public SkipList(int span) {
|
||||||
if(span < 1 || span > SkipSpan.MAX_SIZE)
|
if(span < 1 || span > SkipSpan.MAX_SIZE)
|
||||||
throw new IllegalArgumentException("Invalid span size");
|
throw new IllegalArgumentException("Invalid span size");
|
||||||
first = new SkipSpan(span);
|
first = new SkipSpan<K, V>(span);
|
||||||
stack = new SkipLevels(1, first);
|
stack = new SkipLevels<K, V>(1, first);
|
||||||
//rng = new Random(System.currentTimeMillis());
|
//rng = new Random(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,14 +95,15 @@ public class SkipList {
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(Comparable key, Object val) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public void put(K key, V val) {
|
||||||
if(key == null) { throw new NullPointerException(); }
|
if(key == null) { throw new NullPointerException(); }
|
||||||
if(val == null) { throw new NullPointerException(); }
|
if(val == null) { throw new NullPointerException(); }
|
||||||
SkipLevels slvls = stack.put(stack.levels.length - 1, key, val, this);
|
SkipLevels<K, V> slvls = stack.put(stack.levels.length - 1, key, val, this);
|
||||||
if(slvls != null) {
|
if(slvls != null) {
|
||||||
// grow our stack
|
// grow our stack
|
||||||
//BlockFile.log.info("Top level old hgt " + stack.levels.length + " new hgt " + slvls.levels.length);
|
//BlockFile.log.info("Top level old hgt " + stack.levels.length + " new hgt " + slvls.levels.length);
|
||||||
SkipLevels[] levels = new SkipLevels[slvls.levels.length];
|
SkipLevels<K, V>[] levels = (SkipLevels<K, V>[]) new SkipLevels[slvls.levels.length];
|
||||||
for(int i=0;i < slvls.levels.length; i++) {
|
for(int i=0;i < slvls.levels.length; i++) {
|
||||||
if(i < stack.levels.length) {
|
if(i < stack.levels.length) {
|
||||||
levels[i] = stack.levels[i];
|
levels[i] = stack.levels[i];
|
||||||
@@ -115,12 +117,13 @@ public class SkipList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object remove(Comparable key) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public V remove(K key) {
|
||||||
if(key == null) { throw new NullPointerException(); }
|
if(key == null) { throw new NullPointerException(); }
|
||||||
Object[] res = stack.remove(stack.levels.length - 1, key, this);
|
Object[] res = stack.remove(stack.levels.length - 1, key, this);
|
||||||
if(res != null) {
|
if(res != null) {
|
||||||
if(res[1] != null) {
|
if(res[1] != null) {
|
||||||
SkipLevels slvls = (SkipLevels) res[1];
|
SkipLevels<K, V> slvls = (SkipLevels<K, V>) res[1];
|
||||||
for(int i=0;i < slvls.levels.length; i++) {
|
for(int i=0;i < slvls.levels.length; i++) {
|
||||||
if(stack.levels[i] == slvls) {
|
if(stack.levels[i] == slvls) {
|
||||||
stack.levels[i] = slvls.levels[i];
|
stack.levels[i] = slvls.levels[i];
|
||||||
@@ -129,7 +132,7 @@ public class SkipList {
|
|||||||
stack.flush();
|
stack.flush();
|
||||||
}
|
}
|
||||||
flush();
|
flush();
|
||||||
return res[0];
|
return (V) res[0];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -138,6 +141,7 @@ public class SkipList {
|
|||||||
* dumps all the skip levels
|
* dumps all the skip levels
|
||||||
* @deprecated goes to System.out
|
* @deprecated goes to System.out
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void printSL() {
|
public void printSL() {
|
||||||
System.out.println("List size " + size);
|
System.out.println("List size " + size);
|
||||||
System.out.println(stack.printAll());
|
System.out.println(stack.printAll());
|
||||||
@@ -147,34 +151,36 @@ public class SkipList {
|
|||||||
* dumps all the data
|
* dumps all the data
|
||||||
* @deprecated goes to System.out
|
* @deprecated goes to System.out
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void print() {
|
public void print() {
|
||||||
System.out.println("List size " + size);
|
System.out.println("List size " + size);
|
||||||
System.out.println(first.print());
|
System.out.println(first.print());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(Comparable key) {
|
public V get(K key) {
|
||||||
if(key == null) { throw new NullPointerException(); }
|
if(key == null) { throw new NullPointerException(); }
|
||||||
return stack.get(stack.levels.length - 1, key);
|
return stack.get(stack.levels.length - 1, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkipIterator iterator() { return new SkipIterator(first, 0); }
|
public SkipIterator<K, V> iterator() { return new SkipIterator<K, V>(first, 0); }
|
||||||
|
|
||||||
public SkipIterator min() { return new SkipIterator(first, 0); }
|
/****
|
||||||
|
public SkipIterator<K, V> min() { return new SkipIterator<K, V>(first, 0); }
|
||||||
|
|
||||||
public SkipIterator max() {
|
public SkipIterator<K, V> max() {
|
||||||
SkipSpan ss = stack.getEnd();
|
SkipSpan<K, V> ss = stack.getEnd();
|
||||||
return new SkipIterator(ss, ss.nKeys - 1);
|
return new SkipIterator<K, V>(ss, ss.nKeys - 1);
|
||||||
}
|
}
|
||||||
|
****/
|
||||||
|
|
||||||
/** @return an iterator where nextKey() is the first one greater than or equal to 'key' */
|
/** @return an iterator where nextKey() is the first one greater than or equal to 'key' */
|
||||||
public SkipIterator find(Comparable key) {
|
public SkipIterator<K, V> find(K key) {
|
||||||
int[] search = new int[1];
|
int[] search = new int[1];
|
||||||
SkipSpan ss = stack.getSpan(stack.levels.length - 1, key, search);
|
SkipSpan<K, V> ss = stack.getSpan(stack.levels.length - 1, key, search);
|
||||||
if(search[0] < 0) { search[0] = -1 * (search[0] + 1); }
|
if(search[0] < 0) { search[0] = -1 * (search[0] + 1); }
|
||||||
return new SkipIterator(ss, search[0]);
|
return new SkipIterator<K, V>(ss, search[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Levels adjusted to guarantee O(log n) search
|
// Levels adjusted to guarantee O(log n) search
|
||||||
// This is expensive proportional to the number of spans.
|
// This is expensive proportional to the number of spans.
|
||||||
public void balance() {
|
public void balance() {
|
||||||
@@ -28,18 +28,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
package net.metanotion.util.skiplist;
|
package net.metanotion.util.skiplist;
|
||||||
|
|
||||||
|
import java.io.Flushable;
|
||||||
|
|
||||||
//import net.metanotion.io.block.BlockFile;
|
//import net.metanotion.io.block.BlockFile;
|
||||||
|
|
||||||
public class SkipSpan {
|
public class SkipSpan<K extends Comparable<? super K>, V> implements Flushable {
|
||||||
/** This is actually limited by BlockFile.spanSize which is much smaller */
|
/** This is actually limited by BlockFile.spanSize which is much smaller */
|
||||||
public static final int MAX_SIZE = 256;
|
public static final int MAX_SIZE = 256;
|
||||||
|
|
||||||
public int nKeys = 0;
|
public int nKeys = 0;
|
||||||
public Comparable[] keys;
|
public K[] keys;
|
||||||
public Object[] vals;
|
public V[] vals;
|
||||||
public SkipSpan next, prev;
|
public SkipSpan<K, V> next, prev;
|
||||||
|
|
||||||
public SkipSpan newInstance(SkipList sl) { return new SkipSpan(keys.length); }
|
public SkipSpan<K, V> newInstance(SkipList<K, V> sl) { return new SkipSpan<K, V>(keys.length); }
|
||||||
public void killInstance() { }
|
public void killInstance() { }
|
||||||
public void flush() { }
|
public void flush() { }
|
||||||
|
|
||||||
@@ -48,11 +50,12 @@ public class SkipSpan {
|
|||||||
/*
|
/*
|
||||||
* @throws IllegalArgumentException if size too big or too small
|
* @throws IllegalArgumentException if size too big or too small
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public SkipSpan(int size) {
|
public SkipSpan(int size) {
|
||||||
if(size < 1 || size > MAX_SIZE)
|
if(size < 1 || size > MAX_SIZE)
|
||||||
throw new IllegalArgumentException("Invalid span size " + size);
|
throw new IllegalArgumentException("Invalid span size " + size);
|
||||||
keys = new Comparable[size];
|
keys = (K[]) new Comparable[size];
|
||||||
vals = new Object[size];
|
vals = (V[]) new Object[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** dumps all the data from here to the end */
|
/** dumps all the data from here to the end */
|
||||||
@@ -68,7 +71,7 @@ public class SkipSpan {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int binarySearch(Comparable key) {
|
private int binarySearch(K key) {
|
||||||
int high = nKeys - 1;
|
int high = nKeys - 1;
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int cur;
|
int cur;
|
||||||
@@ -87,12 +90,12 @@ public class SkipSpan {
|
|||||||
return (-1 * (low + 1));
|
return (-1 * (low + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkipSpan getEnd() {
|
public SkipSpan<K, V> getEnd() {
|
||||||
if(next == null) { return this; }
|
if(next == null) { return this; }
|
||||||
return next.getEnd();
|
return next.getEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkipSpan getSpan(Comparable key, int[] search) {
|
public SkipSpan<K, V> getSpan(K key, int[] search) {
|
||||||
if(nKeys == 0) {
|
if(nKeys == 0) {
|
||||||
search[0] = -1;
|
search[0] = -1;
|
||||||
return this;
|
return this;
|
||||||
@@ -109,7 +112,7 @@ public class SkipSpan {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(Comparable key) {
|
public V get(K key) {
|
||||||
if(nKeys == 0) { return null; }
|
if(nKeys == 0) { return null; }
|
||||||
if(keys[nKeys - 1].compareTo(key) < 0) {
|
if(keys[nKeys - 1].compareTo(key) < 0) {
|
||||||
if(next == null) { return null; }
|
if(next == null) { return null; }
|
||||||
@@ -136,8 +139,8 @@ public class SkipSpan {
|
|||||||
nKeys++;
|
nKeys++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void split(int loc, Comparable key, Object val, SkipList sl) {
|
private void split(int loc, K key, V val, SkipList<K, V> sl) {
|
||||||
SkipSpan right = newInstance(sl);
|
SkipSpan<K, V> right = newInstance(sl);
|
||||||
|
|
||||||
if(this.next != null) { this.next.prev = right; }
|
if(this.next != null) { this.next.prev = right; }
|
||||||
right.next = this.next;
|
right.next = this.next;
|
||||||
@@ -173,7 +176,7 @@ public class SkipSpan {
|
|||||||
/**
|
/**
|
||||||
* @return the new span if it caused a split, else null if it went in this span
|
* @return the new span if it caused a split, else null if it went in this span
|
||||||
*/
|
*/
|
||||||
private SkipSpan insert(int loc, Comparable key, Object val, SkipList sl) {
|
private SkipSpan<K, V> insert(int loc, K key, V val, SkipList<K, V> sl) {
|
||||||
sl.addItem();
|
sl.addItem();
|
||||||
if(nKeys == keys.length) {
|
if(nKeys == keys.length) {
|
||||||
// split.
|
// split.
|
||||||
@@ -191,7 +194,7 @@ public class SkipSpan {
|
|||||||
/**
|
/**
|
||||||
* @return the new span if it caused a split, else null if it went in an existing span
|
* @return the new span if it caused a split, else null if it went in an existing span
|
||||||
*/
|
*/
|
||||||
public SkipSpan put(Comparable key, Object val, SkipList sl) {
|
public SkipSpan<K, V> put(K key, V val, SkipList<K, V> sl) {
|
||||||
if(nKeys == 0) {
|
if(nKeys == 0) {
|
||||||
sl.addItem();
|
sl.addItem();
|
||||||
keys[0] = key;
|
keys[0] = key;
|
||||||
@@ -244,7 +247,7 @@ public class SkipSpan {
|
|||||||
* rv[1] is the deleted SkipSpan if the removed object was the last in the SkipSpan.
|
* rv[1] is the deleted SkipSpan if the removed object was the last in the SkipSpan.
|
||||||
* rv is null if no object was removed.
|
* rv is null if no object was removed.
|
||||||
*/
|
*/
|
||||||
public Object[] remove(Comparable key, SkipList sl) {
|
public Object[] remove(K key, SkipList<K, V> sl) {
|
||||||
if(nKeys == 0) { return null; }
|
if(nKeys == 0) { return null; }
|
||||||
if(keys[nKeys - 1].compareTo(key) < 0) {
|
if(keys[nKeys - 1].compareTo(key) < 0) {
|
||||||
if(next == null) { return null; }
|
if(next == null) { return null; }
|
||||||
@@ -268,7 +271,7 @@ public class SkipSpan {
|
|||||||
nKeys = next.nKeys;
|
nKeys = next.nKeys;
|
||||||
//BlockFile.log.error("Killing next span " + next + ") and copying to this span " + this + " in remove of " + key);
|
//BlockFile.log.error("Killing next span " + next + ") and copying to this span " + this + " in remove of " + key);
|
||||||
// Make us point to next.next and him point back to us
|
// Make us point to next.next and him point back to us
|
||||||
SkipSpan nn = next.next;
|
SkipSpan<K, V> nn = next.next;
|
||||||
next.killInstance();
|
next.killInstance();
|
||||||
if (nn != null) {
|
if (nn != null) {
|
||||||
nn.prev = this;
|
nn.prev = this;
|
||||||
@@ -309,7 +312,7 @@ public class SkipSpan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** I2P */
|
/** I2P */
|
||||||
public Comparable firstKey() {
|
public K firstKey() {
|
||||||
return keys[0];
|
return keys[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.i2p.client.naming;
|
package net.i2p.router.naming;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE web-app
|
|
||||||
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
|
|
||||||
"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>
|
|
||||||
<init-param>
|
|
||||||
<param-name>home</param-name>
|
|
||||||
<param-value>./addressbook</param-value>
|
|
||||||
</init-param>
|
|
||||||
<load-on-startup>1</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>addressbook</servlet-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
||||||
14
apps/admin/admin.iml
Normal file
14
apps/admin/admin.iml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="core" />
|
||||||
|
<orderEntry type="module" module-name="router" />
|
||||||
|
<orderEntry type="module" module-name="routerconsole" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -11,8 +11,10 @@ import java.util.Iterator;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.router.Router;
|
import net.i2p.router.Router;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.web.StatsGenerator;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
@@ -47,8 +49,8 @@ class AdminRunner implements Runnable {
|
|||||||
reply(out, "this is not a website");
|
reply(out, "this is not a website");
|
||||||
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
||||||
try {
|
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));
|
_generator.generateStatsPage(new OutputStreamWriter(out), true);
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
@@ -61,8 +63,9 @@ class AdminRunner implements Runnable {
|
|||||||
reply(out, shutdown(command));
|
reply(out, shutdown(command));
|
||||||
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
||||||
try {
|
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));
|
// TODO Not technically the same as router().renderStatusHTML() was
|
||||||
|
_context.routerAppManager().renderStatusHTML(new OutputStreamWriter(out));
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
@@ -80,7 +83,7 @@ class AdminRunner implements Runnable {
|
|||||||
reply.append("Content-type: text/html\n\n");
|
reply.append("Content-type: text/html\n\n");
|
||||||
reply.append(content);
|
reply.append(content);
|
||||||
try {
|
try {
|
||||||
out.write(reply.toString().getBytes());
|
out.write(DataHelper.getASCII(reply.toString()));
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
@@ -97,7 +100,7 @@ class AdminRunner implements Runnable {
|
|||||||
reply.append("Content-type: text/plain\n\n");
|
reply.append("Content-type: text/plain\n\n");
|
||||||
reply.append(content);
|
reply.append(content);
|
||||||
try {
|
try {
|
||||||
out.write(reply.toString().getBytes());
|
out.write(DataHelper.getASCII(reply.toString()));
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
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,
|
||||||
|
}
|
||||||
@@ -5,10 +5,9 @@
|
|||||||
<property name="build" value="build"/>
|
<property name="build" value="build"/>
|
||||||
<property name="dist" location="dist"/>
|
<property name="dist" location="dist"/>
|
||||||
<property name="jar" value="desktopgui.jar"/>
|
<property name="jar" value="desktopgui.jar"/>
|
||||||
<property name="resources" value="resources"/>
|
<property name="javadoc" value="javadoc"/>
|
||||||
<property name="javadoc" value="javadoc"/>
|
|
||||||
<property name="javac.compilerargs" value=""/>
|
<property name="javac.compilerargs" value=""/>
|
||||||
<property name="javac.version" value="1.6" />
|
<property name="javac.version" value="1.7" />
|
||||||
<property name="require.gettext" value="true" />
|
<property name="require.gettext" value="true" />
|
||||||
|
|
||||||
<condition property="no.bundle">
|
<condition property="no.bundle">
|
||||||
@@ -17,9 +16,8 @@
|
|||||||
|
|
||||||
<target name="init">
|
<target name="init">
|
||||||
<mkdir dir="${build}"/>
|
<mkdir dir="${build}"/>
|
||||||
<mkdir dir="${build}/${resources}"/>
|
<mkdir dir="${build}/messages-src"/>
|
||||||
<mkdir dir="${build}/${javadoc}"/>
|
<mkdir dir="${dist}"/>
|
||||||
<mkdir dir="${dist}"/>
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="clean">
|
<target name="clean">
|
||||||
@@ -27,35 +25,36 @@
|
|||||||
<delete dir="${dist}"/>
|
<delete dir="${dist}"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="compile" depends="init">
|
<target name="compile" depends="init">
|
||||||
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
|
||||||
includeAntRuntime="false"
|
includeAntRuntime="false"
|
||||||
srcdir="${src}" destdir="${build}">
|
srcdir="${src}" destdir="${build}">
|
||||||
<compilerarg line="${javac.compilerargs}" />
|
<compilerarg line="${javac.compilerargs}" />
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="../../core/java/build/i2p.jar" />
|
<pathelement location="../../core/java/build/i2p.jar" />
|
||||||
<pathelement location="../../installer/lib/wrapper/all/wrapper.jar" />
|
<pathelement location="../../installer/lib/wrapper/all/wrapper.jar" />
|
||||||
<pathelement location="../../router/java/build/router.jar" />
|
<pathelement location="../../router/java/build/router.jar" />
|
||||||
</classpath>
|
</classpath>
|
||||||
</javac>
|
</javac>
|
||||||
<copy todir="${build}/desktopgui/${resources}">
|
</target>
|
||||||
<fileset dir="${resources}" />
|
|
||||||
</copy>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="bundle" unless="no.bundle">
|
<target name="bundle" unless="no.bundle" depends="init">
|
||||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||||
<env key="JAVA_HOME" value="${java.home}" />
|
<env key="JAVA_HOME" value="${java.home}" />
|
||||||
<arg value="./bundle-messages.sh" />
|
<arg value="./bundle-messages.sh" />
|
||||||
</exec>
|
</exec>
|
||||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||||
<arg value="./bundle-messages.sh" />
|
<arg value="./bundle-messages.sh" />
|
||||||
</exec>
|
</exec>
|
||||||
<!-- multi-lang is optional -->
|
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
|
||||||
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
|
<arg value="./bundle-messages.sh" />
|
||||||
<arg value="./bundle-messages.sh" />
|
</exec>
|
||||||
</exec>
|
<javac source="${javac.version}" target="${javac.version}"
|
||||||
</target>
|
includeAntRuntime="false"
|
||||||
|
srcdir="${build}/messages-src" destdir="${build}">
|
||||||
|
<compilerarg line="${javac.compilerargs}" />
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
|
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
|
||||||
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
|
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
|
||||||
@@ -74,12 +73,18 @@
|
|||||||
<target name="jar" depends="compile, bundle, listChangedFiles" unless="jar.uptodate" >
|
<target name="jar" depends="compile, bundle, listChangedFiles" unless="jar.uptodate" >
|
||||||
<!-- set if unset -->
|
<!-- set if unset -->
|
||||||
<property name="workspace.changes.tr" value="" />
|
<property name="workspace.changes.tr" value="" />
|
||||||
<jar basedir="${build}" destfile="${dist}/${jar}">
|
<!-- ideal for linux: 24x24, but transparency doesn't work -->
|
||||||
|
<copy tofile="${build}/desktopgui/resources/images/logo.png" file="../../installer/resources/themes/console/images/itoopie_xsm.png" />
|
||||||
|
<copy todir="${build}/desktopgui/resources/images" file="images/itoopie_black_24.png" />
|
||||||
|
<copy todir="${build}/desktopgui/resources/images" file="images/itoopie_white_24.png" />
|
||||||
|
<jar basedir="${build}" excludes="messages-src/**" destfile="${dist}/${jar}">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Main-Class" value="net.i2p.desktopgui.Main"/>
|
<attribute name="Main-Class" value="net.i2p.desktopgui.Main"/>
|
||||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||||
|
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||||
|
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# on windows, one must specify the path of commnad find
|
# 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
|
if which find|grep -q -i windows ; then
|
||||||
export PATH=.:/bin:/usr/local/bin:$PATH
|
export PATH=.:/bin:/usr/local/bin:$PATH
|
||||||
fi
|
fi
|
||||||
# Fast mode - update ondemond
|
# 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
|
# add ../java/ so the refs will work in the po file
|
||||||
JPATHS="src"
|
JPATHS="src"
|
||||||
@@ -64,19 +64,19 @@ do
|
|||||||
echo "Updating the $i file from the tags..."
|
echo "Updating the $i file from the tags..."
|
||||||
# extract strings from java and jsp files, and update messages.po files
|
# extract strings from java and jsp files, and update messages.po files
|
||||||
# translate calls must be one of the forms:
|
# translate calls must be one of the forms:
|
||||||
# _("foo")
|
# _t("foo")
|
||||||
# _x("foo")
|
# _x("foo")
|
||||||
# intl._("foo")
|
# intl._t("foo")
|
||||||
# intl.title("foo")
|
# intl.title("foo")
|
||||||
# handler._("foo")
|
# handler._t("foo")
|
||||||
# formhandler._("foo")
|
# formhandler._t("foo")
|
||||||
# net.i2p.router.web.Messages.getString("foo")
|
# net.i2p.router.web.Messages.getString("foo")
|
||||||
# In a jsp, you must use a helper or handler that has the context set.
|
# 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,
|
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||||
# then ant distclean updater.
|
# then ant distclean updater.
|
||||||
find $JPATHS -name *.java > $TMPFILE
|
find $JPATHS -name *.java > $TMPFILE
|
||||||
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 --add-comments\
|
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=handler._ --keyword=formhandler._ \
|
||||||
--keyword=net.i2p.router.web.Messages.getString \
|
--keyword=net.i2p.router.web.Messages.getString \
|
||||||
-o ${i}t
|
-o ${i}t
|
||||||
@@ -105,15 +105,40 @@ do
|
|||||||
# only generate for non-source language
|
# only generate for non-source language
|
||||||
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||||
|
|
||||||
# convert to class files in build
|
msgfmt -V | grep -q '0\.19'
|
||||||
msgfmt --java --statistics -r $CLASS -l $LG -d build $i
|
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
echo "ERROR - msgfmt failed on ${i}, not updating translations"
|
# slow way
|
||||||
# msgfmt leaves the class file there so the build would work the next time
|
# convert to class files in build
|
||||||
find build -name messages_${LG}.class -exec rm -f {} \;
|
msgfmt --java --statistics -r $CLASS -l $LG -d build $i
|
||||||
RC=1
|
if [ $? -ne 0 ]
|
||||||
break
|
then
|
||||||
|
echo "ERROR - msgfmt failed on ${i}, not updating translations"
|
||||||
|
# msgfmt leaves the class file there so the build would work the next time
|
||||||
|
find build -name messages_${LG}.class -exec rm -f {} \;
|
||||||
|
RC=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# fast way
|
||||||
|
# convert to java files in build/messages-src
|
||||||
|
TD=build/messages-src-tmp
|
||||||
|
TDX=$TD/net/i2p/desktopgui
|
||||||
|
TD2=build/messages-src
|
||||||
|
TDY=$TD2/net/i2p/desktopgui
|
||||||
|
rm -rf $TD
|
||||||
|
mkdir -p $TD $TDY
|
||||||
|
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo "ERROR - msgfmt failed on ${i}, not updating translations"
|
||||||
|
# msgfmt leaves the class file there so the build would work the next time
|
||||||
|
find build -name messages_${LG}.class -exec rm -f {} \;
|
||||||
|
RC=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
mv $TDX/messages_$LG.java $TDY
|
||||||
|
rm -rf $TD
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
13
apps/desktopgui/desktopgui.iml
Normal file
13
apps/desktopgui/desktopgui.iml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="core" />
|
||||||
|
<orderEntry type="module" module-name="router" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
BIN
apps/desktopgui/images/itoopie_black_24.png
Normal file
BIN
apps/desktopgui/images/itoopie_black_24.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 558 B |
BIN
apps/desktopgui/images/itoopie_white_24.png
Normal file
BIN
apps/desktopgui/images/itoopie_white_24.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 677 B |
@@ -2,55 +2,94 @@
|
|||||||
# Copyright (C) 2009 The I2P Project
|
# Copyright (C) 2009 The I2P Project
|
||||||
# This file is distributed under the same license as the desktopgui package.
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
# foo <foo@bar>, 2009.
|
#
|
||||||
#
|
# Translators:
|
||||||
|
# ducki2p <ducki2p@gmail.com>, 2011
|
||||||
|
# foo <foo@bar>, 2009
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P desktopgui\n"
|
"Project-Id-Version: I2P\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2011-02-20 11:53+0000\n"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2011-02-26 19:46-0000\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: hamada <hamada@mail.i2p>\n"
|
"Last-Translator: zzzi2p\n"
|
||||||
"Language: ar\n"
|
"Language-Team: Arabic (http://www.transifex.com/otf/I2P/language/ar/)\n"
|
||||||
"Language-Team: duck <duck@mail.i2p>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Language: ar\n"
|
||||||
|
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "ابدأ I2P"
|
msgstr "ابدأ I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "جاري تشغيل I2P"
|
msgstr "جاري تشغيل I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "جاري البدأ"
|
msgstr "جاري البدأ"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr " تشغيل متصفح I2P"
|
msgstr " تشغيل متصفح I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "اعدادات"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "ألغي"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "اعادة تشغيل"
|
msgstr "اعادة تشغيل"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "توقيف I2P"
|
msgstr "توقيف I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "اعدادات الأيقونة"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "هل ترغب في تفعيل الأيقونة؟"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "توقف في مدة {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "إغلاق وشيك"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "الشبكة"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
94
apps/desktopgui/locale/messages_bg.po
Normal file
94
apps/desktopgui/locale/messages_bg.po
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# I2P
|
||||||
|
# Copyright (C) 2009 The I2P Project
|
||||||
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
|
#
|
||||||
|
# Translators:
|
||||||
|
# Gabriel Radev <gabosss@gmail.com>, 2015
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
|
"Last-Translator: zzzi2p\n"
|
||||||
|
"Language-Team: Bulgarian (http://www.transifex.com/otf/I2P/language/bg/)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: bg\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
|
msgid "Start I2P"
|
||||||
|
msgstr "Стартиране на I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "I2P is starting!"
|
||||||
|
msgstr "I2P е стартиран!"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "Starting"
|
||||||
|
msgstr "Стартиране"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
|
msgid "Launch I2P Browser"
|
||||||
|
msgstr "Стартиране на I2P Браузер"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
|
msgid "Restart I2P"
|
||||||
|
msgstr "Рестартиране на I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
|
msgid "Stop I2P"
|
||||||
|
msgstr "Спиране на I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
93
apps/desktopgui/locale/messages_ca.po
Normal file
93
apps/desktopgui/locale/messages_ca.po
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# 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: 2016-05-25 12:29+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
|
"Last-Translator: zzzi2p\n"
|
||||||
|
"Language-Team: Catalan (http://www.transifex.com/otf/I2P/language/ca/)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: ca\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
|
msgid "Start I2P"
|
||||||
|
msgstr "Iniciar I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "I2P is starting!"
|
||||||
|
msgstr "I2P s'està iniciant."
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "Starting"
|
||||||
|
msgstr "Iniciant"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
|
msgid "Launch I2P Browser"
|
||||||
|
msgstr "Iniciar navegador I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
|
msgid "Restart I2P"
|
||||||
|
msgstr "Reiniciar I2P "
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
|
msgid "Stop I2P"
|
||||||
|
msgstr "Aturar I2P "
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Xarxa"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
@@ -7,49 +7,87 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"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"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2012-02-12 19:44+0000\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: Waseihou Watashi <waseihou@gmail.com>\n"
|
"Last-Translator: zzzi2p\n"
|
||||||
"Language-Team: Czech (http://www.transifex.net/projects/p/I2P/language/cs/)\n"
|
"Language-Team: Czech (http://www.transifex.com/otf/I2P/language/cs/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: cs\n"
|
"Language: cs\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
|
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "Spustit I2P"
|
msgstr "Spustit I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "I2P startuje!"
|
msgstr "I2P startuje!"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Startuji"
|
msgstr "Startuji"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "Spouštím I2P Browser"
|
msgstr "Spouštím I2P Browser"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Nastavuji desktopgui"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "Restart I2P"
|
msgstr "Restart I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "Zastavit I2P"
|
msgstr "Zastavit I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Nastavení ikony na liště (tray icon)"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "Zapnout ikonu na liště?"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Síť"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -3,55 +3,93 @@
|
|||||||
# This file is distributed under the same license as the desktopgui package.
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
#
|
#
|
||||||
# <kia___@hushmail.com>, 2011.
|
# Translators:
|
||||||
|
# Aesthese, 2016
|
||||||
|
# KIA <kia___@hushmail.com>, 2011
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"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"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2011-07-12 19:41+0000\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: KIA <kia___@hushmail.com>\n"
|
"Last-Translator: zzzi2p\n"
|
||||||
"Language-Team: Danish (http://www.transifex.net/projects/p/I2P/team/da/)\n"
|
"Language-Team: Danish (http://www.transifex.com/otf/I2P/language/da/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: da\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
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "Start I2P"
|
msgstr "Start I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "I2P starter nu!"
|
msgstr "I2P starter!"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Starter"
|
msgstr "Starter"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "Start I2P Browseren"
|
msgstr "Start I2P Browseren"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Konfigurer desktopgui"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Deaktivere"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "Genstart I2P"
|
msgstr "Genstart I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "Stop I2P"
|
msgstr "Stop I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Konfiguration af processbar ikonet"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "Skal processbar ikonet være aktivt?"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Lukker ned om {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Lukker ned om et øjeblik"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Netværk"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -2,54 +2,96 @@
|
|||||||
# Copyright (C) 2009 The I2P Project
|
# Copyright (C) 2009 The I2P Project
|
||||||
# This file is distributed under the same license as the desktopgui package.
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
# foo <foo@bar>, 2009.
|
#
|
||||||
#
|
# Translators:
|
||||||
|
# blabla <blabla@trash-mail.com>, 2011
|
||||||
|
# Ettore Atalan <atalanttore@googlemail.com>, 2016
|
||||||
|
# foo <foo@bar>, 2009
|
||||||
|
# Lars Schimmer <echelon@i2pmail.org>, 2016
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"Project-Id-Version: I2P\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2014-01-09 18:07+0000\n"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2011-03-22 15:49+0000\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: blabla <blabla@trash-mail.com>\n"
|
"Last-Translator: Lars Schimmer <echelon@i2pmail.org>\n"
|
||||||
"Language-Team: German <>\n"
|
"Language-Team: German (http://www.transifex.com/otf/I2P/language/de/)\n"
|
||||||
"Language: de\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Language: de\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "I2P starten"
|
msgstr "I2P starten"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "I2P startet gerade!"
|
msgstr "I2P startet gerade!"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Startend"
|
msgstr "Startend"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "I2P-Browser öffnen"
|
msgstr "I2P-Browser öffnen"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Desktopgui konfigurieren"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr "I2P System Tray konfigurieren"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Deaktivieren"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "I2P neustarten"
|
msgstr "I2P neustarten"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "I2P beenden"
|
msgstr "I2P beenden"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Systemleistensymbol konfigurieren"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr "I2P sofort neustarten"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "Systemleistensymbol aktivieren?"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr "I2P sofort beenden"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr "Herunterfahren von I2P abbrechen"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Herunterfahren in {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Herunterfahren bevorstehend"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Netzwerk"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr "I2P: Rechtsklick für Menü"
|
||||||
|
|||||||
@@ -4,53 +4,91 @@
|
|||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# <lixtetrax@grhack.net>, 2012.
|
# lixtetrax <lixtetrax@grhack.net>, 2012
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"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"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2012-07-02 11:28+0000\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: lixtetrax <lixtetrax@grhack.net>\n"
|
"Last-Translator: zzzi2p\n"
|
||||||
"Language-Team: Greek (http://www.transifex.com/projects/p/I2P/language/el/)\n"
|
"Language-Team: Greek (http://www.transifex.com/otf/I2P/language/el/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: el\n"
|
"Language: el\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "Έναρξη Ι2Ρ"
|
msgstr "Έναρξη Ι2Ρ"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "Το Ι2Ρ ξεκίνησε!"
|
msgstr "Το Ι2Ρ ξεκίνησε!"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Έναρξη"
|
msgstr "Έναρξη"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "Έναρξη φυλλομετρητή Ι2Ρ"
|
msgstr "Έναρξη φυλλομετρητή Ι2Ρ"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Παραμετροποίηση desktopgui"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Απενεργοποίηση"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "Επανεκκίνηση Ι2Ρ"
|
msgstr "Επανεκκίνηση Ι2Ρ"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "Τερματισμός Ι2Ρ"
|
msgstr "Τερματισμός Ι2Ρ"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Παραμετροποίηση εικονιδίου"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "Ενεργοποίηση εικονιδίου;"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Σβήσιμο σε {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Επίκειται σβήσιμο"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Δίκτυο "
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P desktopgui\n"
|
"Project-Id-Version: I2P desktopgui\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2014-01-09 19:27+0000\n"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
|
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
|
||||||
"Last-Translator: duck <duck@mail.i2p>\n"
|
"Last-Translator: duck <duck@mail.i2p>\n"
|
||||||
"Language-Team: duck <duck@mail.i2p>\n"
|
"Language-Team: duck <duck@mail.i2p>\n"
|
||||||
@@ -18,38 +18,76 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -2,55 +2,96 @@
|
|||||||
# Copyright (C) 2009 The I2P Project
|
# Copyright (C) 2009 The I2P Project
|
||||||
# This file is distributed under the same license as the desktopgui package.
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
# foo <foo@bar>, 2009.
|
#
|
||||||
#
|
# Translators:
|
||||||
|
# ducki2p <ducki2p@gmail.com>, 2011
|
||||||
|
# foo <foo@bar>, 2009
|
||||||
|
# punkibastardo <punkibastardo@gmail.com>, 2011
|
||||||
|
# strel, 2016
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"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"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2011-04-02 23:57+0100\n"
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
"Last-Translator: mixxy <m1xxy@mail.i2p>\n"
|
"Last-Translator: strel\n"
|
||||||
"Language-Team: Spanish (Castilian) <None>\n"
|
"Language-Team: Spanish (http://www.transifex.com/otf/I2P/language/es/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "Iniciar I2P"
|
msgstr "Iniciar I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "I2P está iniciando!"
|
msgstr "I2P está iniciando!"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Iniciando"
|
msgstr "Iniciando"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "Lanzar navegador I2P"
|
msgstr "Lanzar navegador I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Configurar desktopgui"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr "Configurar la bandeja de sistema de I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Deshabilitar"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "Reiniciar I2P"
|
msgstr "Reiniciar I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "Detener I2P"
|
msgstr "Detener I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Configuración del ícono de la barra de tareas"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr "Reiniciar I2P inmediatamente"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "¿Debería estar activado el ícono de la barra de tareas?"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr "Detener I2P inmediatamente"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr "Cancelar el cierre de I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Cierre en {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Cierre inminente"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Red"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr "I2P: Clic secundario para menú"
|
||||||
|
|||||||
95
apps/desktopgui/locale/messages_fa.po
Normal file
95
apps/desktopgui/locale/messages_fa.po
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# 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:
|
||||||
|
# Amir H. Firouzian, 2017
|
||||||
|
# NoProfile, 2016
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
|
"Last-Translator: Amir H. Firouzian\n"
|
||||||
|
"Language-Team: Persian (http://www.transifex.com/otf/I2P/language/fa/)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: fa\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
|
msgid "Start I2P"
|
||||||
|
msgstr "شروع I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "I2P is starting!"
|
||||||
|
msgstr "I2P راه اندازی شد!"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "Starting"
|
||||||
|
msgstr "راه اندازی"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
|
msgid "Launch I2P Browser"
|
||||||
|
msgstr "راه اندازی مرورگر I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
|
msgid "Restart I2P"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
|
msgid "Stop I2P"
|
||||||
|
msgstr "توقف I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr ""
|
||||||
95
apps/desktopgui/locale/messages_fi.po
Normal file
95
apps/desktopgui/locale/messages_fi.po
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# 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:
|
||||||
|
# Jorma Karvonen <karvonen.jorma@gmail.com>, 2015
|
||||||
|
# outolumo <outolumo@gmail.com>, 2015-2016
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
|
"Last-Translator: outolumo <outolumo@gmail.com>\n"
|
||||||
|
"Language-Team: Finnish (http://www.transifex.com/otf/I2P/language/fi/)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: fi\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
|
msgid "Start I2P"
|
||||||
|
msgstr "Käynnistä I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "I2P is starting!"
|
||||||
|
msgstr "I2P on käynnistyy!"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "Starting"
|
||||||
|
msgstr "Käynnistetään"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
|
msgid "Launch I2P Browser"
|
||||||
|
msgstr "Käynnistä I2P-selain"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr "I2P tehtäväpalkin asetukset"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Poista käytöstä"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
|
msgid "Restart I2P"
|
||||||
|
msgstr "Käynnistä I2P uudelleen"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
|
msgid "Stop I2P"
|
||||||
|
msgstr "Pysäytä I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr "Käynnistä I2P uudelleen heti"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr "Pysäytä I2P heti"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr "Peruuta I2P:n sammutus"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Sammuta {0} kuluttua..."
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Sammutus välittömästi"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Verkko"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr "I2P: Valikko hiiren kakkosnapilla"
|
||||||
@@ -2,59 +2,100 @@
|
|||||||
# Copyright (C) 2009 The I2P Project
|
# Copyright (C) 2009 The I2P Project
|
||||||
# This file is distributed under the same license as the desktopgui package.
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# blabla <blabla@trash-mail.com>, 2011
|
# blabla <blabla@trash-mail.com>, 2011
|
||||||
|
# Boxoa590, 2013
|
||||||
# ducki2p <ducki2p@gmail.com>, 2011
|
# ducki2p <ducki2p@gmail.com>, 2011
|
||||||
# foo <foo@bar>, 2009
|
# foo <foo@bar>, 2009
|
||||||
|
# French language coordinator <french.coordinator@rbox.me>, 2017
|
||||||
|
# French language coordinator <french.coordinator@rbox.me>, 2017
|
||||||
# Boxoa590, 2013
|
# Boxoa590, 2013
|
||||||
|
# Towinet, 2016
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: I2P\n"
|
"Project-Id-Version: I2P\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2014-01-09 19:14+0000\n"
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
"PO-Revision-Date: 2013-06-08 04:50+0000\n"
|
"PO-Revision-Date: 2017-07-04 12:05+0000\n"
|
||||||
"Last-Translator: Boxoa590\n"
|
"Last-Translator: French language coordinator <french.coordinator@rbox.me>\n"
|
||||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
"Language-Team: French (http://www.transifex.com/otf/I2P/language/fr/)\n"
|
||||||
"fr/)\n"
|
|
||||||
"Language: fr\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: fr\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
msgid "Start I2P"
|
msgid "Start I2P"
|
||||||
msgstr "Démarrer I2P"
|
msgstr "Démarrer I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "I2P is starting!"
|
msgid "I2P is starting!"
|
||||||
msgstr "I2P démarre !"
|
msgstr "I2P démarre !"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
msgid "Starting"
|
msgid "Starting"
|
||||||
msgstr "Démarrage"
|
msgstr "Démarrage"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
msgid "Launch I2P Browser"
|
msgid "Launch I2P Browser"
|
||||||
msgstr "Lancer le navigateur I2P"
|
msgstr "Lancer le navigateur d'I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
msgid "Configure desktopgui"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
msgstr "Configurer l'interface de bureau"
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr "Configurer la zone de notification d'I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Désactiver"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
msgid "Restart I2P"
|
msgid "Restart I2P"
|
||||||
msgstr "Redémarrer I2P"
|
msgstr "Redémarrer I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
msgid "Stop I2P"
|
msgid "Stop I2P"
|
||||||
msgstr "Arrêter I2P"
|
msgstr "Arrêter I2P"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:43
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
msgid "Tray icon configuration"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
msgstr "Configuration de l'icône de notification"
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr "Redémarrer I2P immédiatement"
|
||||||
|
|
||||||
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:46
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
msgid "Should tray icon be enabled?"
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
msgstr "Activer l'icône de notification ?"
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr "Arrêter I2P immédiatement"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr "Annuler la fermeture d'I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Fermeture dans {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "La fermeture est imminente"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Réseau"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr "I2P : clic droit pour obtenir le menu"
|
||||||
|
|||||||
94
apps/desktopgui/locale/messages_gl.po
Normal file
94
apps/desktopgui/locale/messages_gl.po
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# I2P
|
||||||
|
# Copyright (C) 2009 The I2P Project
|
||||||
|
# This file is distributed under the same license as the desktopgui package.
|
||||||
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
|
#
|
||||||
|
# Translators:
|
||||||
|
# Uberius Crypto <uberius@anonymail.tech>, 2016
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||||
|
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
|
||||||
|
"Last-Translator: Uberius Crypto <uberius@anonymail.tech>\n"
|
||||||
|
"Language-Team: Galician (http://www.transifex.com/otf/I2P/language/gl/)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Language: gl\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||||
|
msgid "Start I2P"
|
||||||
|
msgstr "Iniciar I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "I2P is starting!"
|
||||||
|
msgstr "I2P está a se iniciar!"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||||
|
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||||
|
msgid "Starting"
|
||||||
|
msgstr "Iniciando"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||||
|
msgid "Launch I2P Browser"
|
||||||
|
msgstr "Lanzar Navegador I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||||
|
msgid "Configure I2P System Tray"
|
||||||
|
msgstr "Configurar a Bandexa do Sistema I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Inhabilitar"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||||
|
msgid "Restart I2P"
|
||||||
|
msgstr "Reiniciar I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||||
|
msgid "Stop I2P"
|
||||||
|
msgstr "Deter I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||||
|
msgid "Restart I2P Immediately"
|
||||||
|
msgstr "Reiniciar I2P Inmediatamente"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||||
|
msgid "Stop I2P Immediately"
|
||||||
|
msgstr "Deter I2P Inmediatamente"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||||
|
msgid "Cancel I2P Shutdown"
|
||||||
|
msgstr "Cancelar Apagado I2P"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||||
|
#, java-format
|
||||||
|
msgid "Shutdown in {0}"
|
||||||
|
msgstr "Apagar en {0}"
|
||||||
|
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||||
|
msgid "Shutdown imminent"
|
||||||
|
msgstr "Apagar de contado"
|
||||||
|
|
||||||
|
#. status translations are in the console bundle
|
||||||
|
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Rede"
|
||||||
|
|
||||||
|
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||||
|
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||||
|
msgid "I2P: Right-click for menu"
|
||||||
|
msgstr "I2P: Clic co botón dereito para acceder ó menú"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user