Compare commits
973 Commits
i2pbote_0_
...
v0.4.1
Author | SHA1 | Date | |
---|---|---|---|
d3cb0ab3f6 | |||
e5fa4706db | |||
ecdd2ee426 | |||
784a716f0a | |||
afdde691b4 | |||
65d9439e03 | |||
8d19c4c78a | |||
8731a72887 | |||
9e1b42134c | |||
17b4d035eb | |||
d967d50c51 | |||
42770cf01b | |||
c910e17f6c | |||
d408242173 | |||
c52429f393 | |||
aac9df446f | |||
da40d97185 | |||
e661e4306c | |||
18005cdfb3 | |||
1a7e8daf8e | |||
771153c4d7 | |||
f1e750cef1 | |||
52e30278b5 | |||
4f1b81510f | |||
0c4d1dc5c3 | |||
c1934b4576 | |||
0edd014c6b | |||
27e02ce527 | |||
9aa14a705e | |||
219de6e499 | |||
d07f790dbb | |||
8abfc8345b | |||
3cbcfaa331 | |||
63b63a9f65 | |||
29f5db767d | |||
90545b7046 | |||
37b64f25c0 | |||
5f7bb2d7d1 | |||
69fc637bd7 | |||
cb0b0822a3 | |||
f83f7cd085 | |||
bab92e082f | |||
d1e7eeb7bc | |||
a5409b0e43 | |||
742c697150 | |||
42c6269cda | |||
03012e5323 | |||
97825a3d60 | |||
dc5d066775 | |||
c2bc331b55 | |||
8f29c7d6fb | |||
6b530a364b | |||
3f60643c2e | |||
3539b5a13b | |||
e37f70506d | |||
4196486799 | |||
6dbecc0f6e | |||
d209c9f94b | |||
6e528dae6a | |||
90f9de4861 | |||
f7b3499e93 | |||
5901565d74 | |||
f98990ad65 | |||
d290665a17 | |||
e2e2233b89 | |||
29190552d9 | |||
371ae89bc3 | |||
a34da62789 | |||
8ff2c84cd4 | |||
96140a49c5 | |||
b3f9ea8a0b | |||
034660d4af | |||
bbda61316e | |||
297a26cc63 | |||
c9686adaef | |||
82d31e4813 | |||
63c17045b6 | |||
0566e42f21 | |||
a21f67d429 | |||
d7ae6d51e5 | |||
271eb004b2 | |||
c65e3f8f7e | |||
dd7f4055a1 | |||
9b0836249d | |||
0585f211fb | |||
4df989d63a | |||
a76789cf30 | |||
ae55336e06 | |||
437c5ddbac | |||
63a574f578 | |||
42c3e0d369 | |||
5d89032b90 | |||
fc738142fa | |||
4e9b0e93cb | |||
8912cfcf7d | |||
73e22a3d34 | |||
dfa1dfbd74 | |||
eff95792ac | |||
bf53778367 | |||
74bde7aac6 | |||
848ec8cb14 | |||
a72bd3fb04 | |||
87ce7646f6 | |||
e2c003503a | |||
4f9d717725 | |||
f638d8e43a | |||
2377acf15c | |||
f11af022b2 | |||
9ef5a15650 | |||
02bb52dc67 | |||
bd9a0bd6b4 | |||
fe7516c24f | |||
97c567a105 | |||
62308d053d | |||
f4ebc330a1 | |||
93cabe4f44 | |||
5222861962 | |||
9c09c739d2 | |||
8b3770f33d | |||
cd5d8b0ac2 | |||
596aa39d5d | |||
212ca673b0 | |||
9833590266 | |||
77242920bd | |||
19a8c09a8d | |||
2634398ea4 | |||
2fac3e9eae | |||
182bafb524 | |||
d7c673e4be | |||
33273675da | |||
7b405764fb | |||
750305fef1 | |||
269f0d07e9 | |||
7aae76ef4b | |||
302414a53d | |||
22732d33c1 | |||
b113dd3e51 | |||
ca0ac05614 | |||
54ac8425b5 | |||
67e36d834e | |||
48c2294517 | |||
e3e694d0c9 | |||
06fc60af43 | |||
9cd8bddf8a | |||
6c4ab4b1b3 | |||
3155308054 | |||
538a5b2e06 | |||
dd126df6c7 | |||
a1edb3173c | |||
edc51acedb | |||
0394b591a7 | |||
9a5a161342 | |||
ec3acae530 | |||
7fea66978b | |||
b7abb03b32 | |||
958a072d9b | |||
e7042dc5a7 | |||
bc6df473be | |||
04ac90d478 | |||
7e8421c63b | |||
3591d25f72 | |||
1f1b328f70 | |||
823491ae4d | |||
6856773636 | |||
2cc3df7c1f | |||
852bad8d61 | |||
4f357db8ec | |||
877b02cc04 | |||
8b5b7507c6 | |||
5ff770bc31 | |||
4107467c64 | |||
05def741fb | |||
82ac0d59d8 | |||
10445e1082 | |||
a968f5c6f4 | |||
d6564680a5 | |||
ec41d7d82e | |||
8a29b9dd0d | |||
6c53344f51 | |||
2768297be9 | |||
740197e439 | |||
6e4c52b746 | |||
cc59ed9adb | |||
3c0a431f09 | |||
392ba71037 | |||
e39abcc145 | |||
e030e9ed5f | |||
1896fccf1f | |||
ca19e9d9e0 | |||
729a4ac99f | |||
729f59e729 | |||
78b66b5509 | |||
5cdcae1416 | |||
348262e7a2 | |||
adb290658a | |||
c04fc24445 | |||
4762f8486e | |||
52a717d7e3 | |||
e9ffb4643b | |||
382f75f4a4 | |||
4a6fc262e7 | |||
4cd24cd579 | |||
32ce92d7cb | |||
96bb3a0719 | |||
5cebc0b2ee | |||
4e7d57d8e3 | |||
0ad03ce6d4 | |||
2082fd0856 | |||
98c56de3a5 | |||
1801e308b2 | |||
f318587209 | |||
38d5833551 | |||
6bbd015d38 | |||
f20ae940a8 | |||
f7f185a68c | |||
a47100d14a | |||
32bd6e45a8 | |||
ca19b0929e | |||
3dede23a24 | |||
e190587330 | |||
0d92ddb6e1 | |||
52f6405c74 | |||
99fb8bf264 | |||
fa22d47252 | |||
2dfa656b06 | |||
56aa3f3c1c | |||
c2e75290fb | |||
3387cdd90c | |||
c3088c5931 | |||
a149a0bdc0 | |||
7867198fe9 | |||
38293ebcf9 | |||
6f4a0615ff | |||
22fa6105ac | |||
946fa8d6ec | |||
5a8d9c6f4f | |||
5c53c2071b | |||
c84770036d | |||
d9756407b0 | |||
fe9c6d9d47 | |||
ee96addef6 | |||
1f9aa61d2f | |||
5e559846db | |||
bbd24eaaff | |||
4db680f067 | |||
79595913f2 | |||
b387b77bfb | |||
dce43d11ae | |||
8fec6b28e8 | |||
17282cda4d | |||
1664253417 | |||
654b136cb0 | |||
2b5de7958e | |||
10b9b2e593 | |||
3571adf2ec | |||
44027e80ca | |||
9d821f66b9 | |||
bef847d270 | |||
967a523130 | |||
c35e9c9139 | |||
c0b62e25c1 | |||
936e1e7d50 | |||
592793eaac | |||
f1c9ac9788 | |||
bdd24d7e9d | |||
de36d91909 | |||
1a6ae22b99 | |||
adde9736be | |||
173d08d798 | |||
acb1ace33a | |||
ffa7450e77 | |||
d9d9c47124 | |||
d960308461 | |||
616df8de9f | |||
427e293bac | |||
163f8d58c0 | |||
43e34eb221 | |||
c2d1334c04 | |||
a05890eaec | |||
2a744fb1cd | |||
ed60728edd | |||
48e69d3cd5 | |||
df09332ead | |||
585413fa2b | |||
68c48cb332 | |||
ae87a801ea | |||
901b051546 | |||
6590e3122a | |||
e601b5f46e | |||
641085ab24 | |||
5d371f983a | |||
8fc111fc86 | |||
2dc809c025 | |||
7b0149dc39 | |||
24509df2b5 | |||
263b68550e | |||
ae3ac8b5be | |||
7c22899f32 | |||
3970d6d015 | |||
4464301119 | |||
f0622d202b | |||
63e260f932 | |||
87ad8db92a | |||
cc7e0209ec | |||
1a4c25a32f | |||
79339a0208 | |||
249389a4d3 | |||
92a5a998d6 | |||
e1a49cf440 | |||
e30cb79c5f | |||
49268b21ea | |||
74384e0517 | |||
9bfde0ac33 | |||
55d5ea6084 | |||
0e36c3dcc3 | |||
0155e5f57f | |||
a2b3833602 | |||
200d9ceb3d | |||
69fd2431c8 | |||
66020b2fc7 | |||
34e76ce627 | |||
79393f0ea8 | |||
c4cdbb98cc | |||
eda69d1e7e | |||
1f2c528b9b | |||
6a99b034b7 | |||
17db81eee1 | |||
d50c843145 | |||
7cbf364407 | |||
bd8674950e | |||
0a0418f83f | |||
a5832cd1e4 | |||
ccbc2c3e01 | |||
d5c6c2d046 | |||
d8a606946e | |||
dbaa00d5b1 | |||
844bfcb842 | |||
882a6d207a | |||
730aff2a50 | |||
de6d2d60a9 | |||
a724a521cd | |||
eaaf3c90e4 | |||
a0febacdfd | |||
2f0cb066ab | |||
fc89896246 | |||
e9c262c8b7 | |||
093e439e04 | |||
bf07f9c664 | |||
bba9ac405a | |||
a0457273b7 | |||
e6a330944d | |||
20940f209b | |||
bbc71ad13c | |||
64917757a4 | |||
b966ebbcfd | |||
ca7f4124c4 | |||
b24fe46661 | |||
1db3aee096 | |||
db5a566e15 | |||
f485c68472 | |||
78013d6725 | |||
261d05a1d6 | |||
4a79a28d28 | |||
844a7a24fe | |||
9937ec73f9 | |||
54629d8d05 | |||
15dcd78936 | |||
087a4a68be | |||
7829c44d0d | |||
476d06a588 | |||
53223be28d | |||
691b8ade1c | |||
7ac255ec94 | |||
cf84a6aeee | |||
15c45ad820 | |||
10100b8177 | |||
6adef679ac | |||
00411877ad | |||
7dc9f6caa0 | |||
dcb2b0f945 | |||
f396729698 | |||
0aff058acd | |||
55f363aa73 | |||
6fec35ce85 | |||
42001079b5 | |||
ab3d23a3af | |||
3b0c9774e5 | |||
8b44166b90 | |||
46ca0add8a | |||
6e967b2365 | |||
bc72ebb865 | |||
e204d01fa2 | |||
4a05868f11 | |||
6400913229 | |||
d7d3f2f01c | |||
f9014d7b7b | |||
a64ece90c2 | |||
e8f16cc83c | |||
d7b7355dd1 | |||
816cf49b8c | |||
bf2e2224c9 | |||
2824c9a773 | |||
1dbbcd8b78 | |||
d7d6257a36 | |||
020ef33b95 | |||
8cfe4c5660 | |||
e04deb28a1 | |||
fc0837ede4 | |||
3ade199175 | |||
7bffe19e9e | |||
3ffcf9d8d3 | |||
111b3d8dbb | |||
e177cd4567 | |||
a0ce9017a9 | |||
bc1848ddcf | |||
1f595fc079 | |||
22c0b789c4 | |||
967286aed0 | |||
ef357a5f2a | |||
9fb05ba42e | |||
f13743d7b9 | |||
549c39681d | |||
a3e8f657dd | |||
9cb3409a1a | |||
5e87d6fa2d | |||
902db81fa7 | |||
3cd0f09a41 | |||
d0204effa2 | |||
ec619dd830 | |||
10e3df428c | |||
e11f41d7f2 | |||
f7aae2de4e | |||
d1e4d1a715 | |||
9435b23ab2 | |||
bdffd2b8c4 | |||
590b9a9e05 | |||
86ec61db22 | |||
45f60e9242 | |||
56be74a167 | |||
14376afddb | |||
d2adcd64a7 | |||
13c19addff | |||
dad6a579c1 | |||
83d585f651 | |||
90ceef4583 | |||
0bf899e291 | |||
bbdfc5745b | |||
c3e6a437c9 | |||
dbe4400409 | |||
bb5d075a54 | |||
5d87d5ec00 | |||
d24eea365c | |||
abd4a55956 | |||
732b14115b | |||
4455fbb172 | |||
673d43cd86 | |||
b45a162826 | |||
b06d07b5d1 | |||
52ac133ffa | |||
4a240fbb5b | |||
252a7f0dad | |||
1cd51c811d | |||
dda1f5b585 | |||
fb5e1fc4c2 | |||
0e6a32a0a0 | |||
d9bc25e1aa | |||
b124a1046d | |||
cd21435b60 | |||
44130323ad | |||
ef339c29d0 | |||
8ea8e86d99 | |||
0edf2cfbe3 | |||
a4b284a71c | |||
e1b9eb5bbc | |||
f45a185502 | |||
be545c0836 | |||
6c10b8ac64 | |||
92ff6b58f0 | |||
1f54ed9ba8 | |||
19452867b4 | |||
1fe6c4fc36 | |||
57ead77d39 | |||
dd3ed14174 | |||
efc2363ade | |||
19a586b170 | |||
3851faff3f | |||
a583a1fcc3 | |||
0464c76884 | |||
2bc05d4d46 | |||
19970b1d53 | |||
035cd346a4 | |||
cb1d5bbf67 | |||
058d09d262 | |||
14c728c588 | |||
7823b38d24 | |||
cb76489c0f | |||
fb0352cd7e | |||
b7fcbb5829 | |||
80a04a70cb | |||
b48534b5f7 | |||
a1085909e1 | |||
dc7777be7f | |||
0ed58252d9 | |||
660b77c112 | |||
1c2fe9a481 | |||
dc2d8397ab | |||
926a06e53c | |||
7de621dc82 | |||
35bf2b930a | |||
307e4e8863 | |||
04569977d5 | |||
b11bd7b53b | |||
4f42050cf2 | |||
4b95f34430 | |||
e10933cc0e | |||
db4c3f23cd | |||
3ff443fcc8 | |||
3c302441ea | |||
250f12a69f | |||
cc15bff91b | |||
9b8828109c | |||
72e033e2ef | |||
08f96661fa | |||
7bfffe413c | |||
1425a641ae | |||
8ed88d1331 | |||
a99c08d0e7 | |||
c1191d803c | |||
844f1d3741 | |||
612753b39e | |||
cecccddc2e | |||
17073ed8cd | |||
efe14faae4 | |||
08aa68d257 | |||
2b9b19030f | |||
87b70ff7bc | |||
6776b87040 | |||
210ad7f767 | |||
3960e41534 | |||
32fc56754a | |||
082f553be4 | |||
bcb31dca0a | |||
a508fa1a0f | |||
dbf769a8cb | |||
f3825f3890 | |||
4125ada488 | |||
6a425d1880 | |||
173c89306f | |||
8c6e3bedfb | |||
db9a13d58d | |||
fa37238e00 | |||
2f10c2bb29 | |||
437686b1e6 | |||
53508009b9 | |||
49ff872b88 | |||
115688de03 | |||
346d0cd822 | |||
e51c29565e | |||
15f209844d | |||
86a50c7986 | |||
5d44198fef | |||
3ab31b8b16 | |||
4bbab19d14 | |||
d532c6117d | |||
63dc3ea208 | |||
82cb40e9bf | |||
ec0b072fca | |||
4718424d11 | |||
4300ce67e8 | |||
c58a8bb562 | |||
55859d669b | |||
e11e80832a | |||
e5f7e1e78f | |||
6893f5b487 | |||
d56ccaf436 | |||
1110bbe386 | |||
65290098e6 | |||
5fd314753b | |||
8dd98f2733 | |||
d33882848f | |||
0e174f870c | |||
6954e5c7a8 | |||
8de6a0ab07 | |||
d7cf897072 | |||
596d19d212 | |||
4e44fc204e | |||
277a535be4 | |||
1dbd6ebc4c | |||
bcf869586f | |||
6b5bc59775 | |||
17feb49b0a | |||
9625566913 | |||
b2a3308c2e | |||
89e5a195f8 | |||
e4c130f51f | |||
899c0f6796 | |||
fc1287a016 | |||
fd3ca21a0c | |||
789f8ddc3f | |||
bda40109ed | |||
8c44d3890d | |||
0e2b89dff1 | |||
7c46127738 | |||
d33b8da111 | |||
5d6c30f0bb | |||
7008c26545 | |||
b8597014dd | |||
0457bd307f | |||
eb446f8703 | |||
9df307365c | |||
fcd4fb63ed | |||
27713fb7b6 | |||
0db3ce5026 | |||
0f04c2c51a | |||
206be17615 | |||
2511c5b851 | |||
4db98b2c2b | |||
8d2d360180 | |||
7d7b509eb9 | |||
124ca1ba62 | |||
e9cd4a9f6c | |||
c627299a35 | |||
e0f183efa8 | |||
89395885ba | |||
a77309ab36 | |||
efd04f322c | |||
a12f90d432 | |||
5919da4930 | |||
2d291f1ce2 | |||
e299d2e83d | |||
76551e3d3f | |||
2f134bfbe4 | |||
c03c481b94 | |||
7d1fed76da | |||
7148172e9c | |||
5c102da3a0 | |||
f3a1c618e5 | |||
5c221f31d9 | |||
7ac42c0e4e | |||
4da3ee6aed | |||
3aecc56933 | |||
5ea124b7d2 | |||
7fb33a0d35 | |||
6d2878db5c | |||
9bee5057f1 | |||
bdce2ecad5 | |||
d3ee66ff60 | |||
647efead3b | |||
09f5d107c9 | |||
d33bc11a31 | |||
2d6066ad58 | |||
0bdd216ef0 | |||
75336e899d | |||
3870ca5335 | |||
5aaae853af | |||
a64cdca34e | |||
99f64adc05 | |||
05c24ab545 | |||
897d43ff51 | |||
46b9e3a039 | |||
018209bed5 | |||
fe14f97dfd | |||
f2b1d3cc1c | |||
0600b6e595 | |||
aab0b139d3 | |||
872c386929 | |||
23f57da28e | |||
7fbd29b75d | |||
b8fd5b5c1d | |||
c81f2cb46c | |||
6c859388c5 | |||
087b8ddc42 | |||
0eba059a8c | |||
7136ab215c | |||
3f867d8041 | |||
a8bb3652fe | |||
1672d95ae6 | |||
c3c832649c | |||
c115278016 | |||
a65653b30b | |||
d92f66720a | |||
0954398245 | |||
50da5ccc80 | |||
2b71438c82 | |||
1b5356e845 | |||
9c951dc2f1 | |||
117c35cc5a | |||
dbd46e2b4f | |||
a2c55a78fc | |||
c423b7331e | |||
a031f4da28 | |||
7573eed929 | |||
1e78638692 | |||
19ea512d79 | |||
b9155254d0 | |||
0ebe7e68c7 | |||
48340cb790 | |||
02b803fda7 | |||
4d306d5f85 | |||
388843a439 | |||
e03521821a | |||
ac77853485 | |||
ce664ebf8b | |||
93041cb1d4 | |||
d68fd5429e | |||
a7b4b9acc6 | |||
20841b7a4a | |||
e7f186b7f3 | |||
2a2adc6645 | |||
9989940693 | |||
f71f0e1470 | |||
3c7bd9acf6 | |||
1439358221 | |||
0895c3c976 | |||
8a6c6c2627 | |||
c3883bb069 | |||
4e5104ff52 | |||
ecf093119a | |||
cbd7a8dffb | |||
08cd5406f4 | |||
af2f63565f | |||
1b481dcf24 | |||
6ee5005944 | |||
b4b94ad38a | |||
aa4551fc14 | |||
9d77f57123 | |||
3115faedb2 | |||
4e7b0c115e | |||
c28c99060b | |||
d3a072c54b | |||
174a94f492 | |||
9f6806a738 | |||
809dc90bc8 | |||
c14faf5fc4 | |||
d9034fee31 | |||
c30180fcbf | |||
110a4bd484 | |||
06106c0b57 | |||
a006e3b688 | |||
d37911e5b1 | |||
b128693296 | |||
85d958a0cc | |||
ca1d5e6d8c | |||
245e50aaa9 | |||
4d0d5d245c | |||
f1d8554ab3 | |||
c76a33fa69 | |||
5a3e49c4dd | |||
2ad8d2ac8e | |||
d0c4fd7ca8 | |||
6b38f0d520 | |||
0105bb360a | |||
35d22a9638 | |||
2cce8c9a7a | |||
a525c3d920 | |||
8f090fd3e3 | |||
c36b24bad6 | |||
9b8fd8e6fc | |||
078f0952ef | |||
834331903e | |||
b112ad89f3 | |||
73f8295c9c | |||
c2da679543 | |||
ac46459a0d | |||
c663415ebc | |||
68f9360f40 | |||
e0436d1e43 | |||
a488294bb3 | |||
175345dfe4 | |||
78bb4f7366 | |||
29f485f4e2 | |||
b794aaf0e0 | |||
465d509bcc | |||
a4b25f0ae8 | |||
7feba2f15e | |||
2e72fb7f36 | |||
a225fa20b1 | |||
f87fe26811 | |||
d2b38a3f33 | |||
ef8a143eb0 | |||
e33d186ed0 | |||
0527c1f246 | |||
7ee570e375 | |||
c7182a27cf | |||
f972c9e2e6 | |||
29df785ab6 | |||
e3448c9b17 | |||
a3a8c77963 | |||
67dab8aaf7 | |||
7c2fc47933 | |||
0a3a2bedf8 | |||
38ab0630af | |||
d6be15ca4d | |||
77ec925d45 | |||
2bd6eac5af | |||
50673b6358 | |||
ee578e7b06 | |||
4025734680 | |||
2bbba38007 | |||
479b28f35f | |||
07a3340ffa | |||
69f289b0d9 | |||
308330c8a0 | |||
aac785dda8 | |||
6bd4cab290 | |||
816eb59c94 | |||
889a28063d | |||
a783a0ddb8 | |||
617122dfe1 | |||
e471ddd57a | |||
1999eb2432 | |||
a22eea0f66 | |||
62a1a85a8f | |||
00fbabded2 | |||
53a052382f | |||
66b970d22b | |||
2b5ce8cf27 | |||
408f63bdf9 | |||
1ce75177e9 | |||
0df770bc68 | |||
120de4af9e | |||
b557973e79 | |||
6b833622cf | |||
99baa56af3 | |||
95ac52b7ea | |||
e4696b2bad | |||
00226dfe4d | |||
c0ad846a3d | |||
9a0226674f | |||
5d5a4bc50f | |||
2976f10d92 | |||
9ac0fd128d | |||
4062cfa97c | |||
ff0d6e2ff2 | |||
9461bc1edb | |||
f06e936e10 | |||
f90f6059c3 | |||
f529cd3db0 | |||
a9a0a5202e | |||
67a871814e | |||
24d2f2fd9a | |||
c3a3a19751 | |||
37643b15b7 | |||
defbb68445 | |||
744c1c1b61 | |||
88e0f5c081 | |||
01eb01dc24 | |||
03dac6db84 | |||
535dd76c8e | |||
e211b1040c | |||
8533790aa3 | |||
09a271ba12 | |||
09337fa259 | |||
97a93db976 | |||
9c9b4b5404 | |||
9212075b08 | |||
0c95890d77 | |||
135190058a | |||
ff87fa0a78 | |||
ed1b2bcdd2 | |||
6b796c1715 | |||
cdfbd98612 | |||
8e471d84a1 | |||
db72661f57 | |||
5524b4b563 | |||
6488aeac56 | |||
91e6daa303 | |||
f56c3ca1bf | |||
8c5b402edf | |||
50eb754d19 | |||
ae41a90478 | |||
892a795c68 | |||
d2634bd130 | |||
6a482911b3 | |||
35f1320ef1 | |||
6a9729f898 | |||
a064857ff5 | |||
3fab712da7 | |||
d4542b8449 | |||
366fa10ce8 | |||
050a6dbbbc | |||
8bb3313f38 | |||
e7575018bc | |||
863b58913a | |||
6d581f37a9 | |||
8c152f27d8 | |||
07fdac2312 | |||
e467e6232a | |||
6e2a14af39 | |||
f23db925ad | |||
93bf69d0aa | |||
cd74c6aac2 | |||
240a8c12eb | |||
4888f0dd54 | |||
7c5aa40d26 | |||
d9fb751b7b | |||
a23983f686 | |||
561b4244d6 | |||
331f72ef67 | |||
bea47a0c5d | |||
232e6f72e7 | |||
1557694beb | |||
1824e0ddcc | |||
d6d0756a6b | |||
c08eff08db | |||
7664dcbd5b | |||
1e666ca7de | |||
56baffba77 | |||
529b39efe9 | |||
a826750254 | |||
cff2752b8f | |||
3daa866b10 | |||
e1e1a7a8e4 | |||
b76288e944 | |||
905f9aa974 | |||
57a2d2b891 | |||
7d060c495a | |||
e2c83d58da | |||
f5a73349fb | |||
f02148e159 | |||
e03a6640fb | |||
a4c37841ec | |||
b44f67011f | |||
a5765a5920 | |||
ae7c0947cf | |||
af9e46c983 | |||
eb39dfdb90 | |||
6b5ad92ea6 | |||
d60f26561a | |||
f36d0f2298 | |||
c796311c55 | |||
4ee42e9a1f | |||
33ce63db4e | |||
340d6cd83b | |||
560f6e4946 | |||
6445dd5d4c | |||
86fe700d9f | |||
d2d4031f2e | |||
e598b81600 | |||
7f9f55fbac | |||
a707f2830b | |||
0f95825828 | |||
c764008170 | |||
dc43492537 | |||
e87a4efe2f | |||
95cfab5e71 | |||
ab1ad92278 | |||
f2afa866f9 | |||
de53a1fbc9 | |||
97f078721b | |||
52f295396c | |||
ade9804ae6 | |||
7fb9cb8290 | |||
3d262db251 | |||
d093f81e46 | |||
1c2af589fd | |||
daa289bed1 | |||
40ad4cd488 | |||
d9931f519d | |||
78a5d59ef3 | |||
c4be1543ce | |||
2652d75346 | |||
72621a20c9 | |||
960f480d3a | |||
d8f7d8bfb2 | |||
4b0fdf6932 | |||
739e517c3f | |||
0af131b043 | |||
b780f79e30 | |||
6fcaf3761c | |||
9bf0f45ad0 | |||
d23ac867a4 | |||
3195fd1cb3 |
69
.mtn-ignore
Normal file
@ -0,0 +1,69 @@
|
||||
# Just to try and prevent some noob disasters.
|
||||
# Use mtn add --no-respect-ignore foo.jar to ignore this ignore list
|
||||
|
||||
# Temporary/build files
|
||||
i2pbote.jar
|
||||
i2pbote.xpi2p
|
||||
i2pbote-update.xpi2p
|
||||
~$
|
||||
|
||||
# Temporary/build dirs
|
||||
^ant_build
|
||||
^plugin/plugin.tmp
|
||||
|
||||
# Build property overrides
|
||||
override.properties
|
||||
|
||||
# Downloaded JavaMail libraries
|
||||
mailapi-.*.jar
|
||||
|
||||
# Downloaded BouncyCastle Provider libraries
|
||||
bcprov-jdk15on-.*.jar
|
||||
|
||||
# Downloaded IMAP libraries
|
||||
apache-james-imap-api-0.4-.*.jar
|
||||
apache-james-imap-message-0.4-.*.jar
|
||||
apache-james-imap-processor-0.4-.*.jar
|
||||
apache-james-mailbox-api-0.6-.*.jar
|
||||
apache-james-mailbox-store-0.6-.*.jar
|
||||
apache-mime4j-core-.*.jar
|
||||
apache-mime4j-dom-.*.jar
|
||||
commons-codec-.*.jar
|
||||
commons-collections-.*.jar
|
||||
commons-configuration-.*.jar
|
||||
commons-io-.*.jar
|
||||
commons-lang-.*.jar
|
||||
james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar
|
||||
james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar
|
||||
james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar
|
||||
james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar
|
||||
james-server-util-3.0.0-beta5-SNAPSHOT.jar
|
||||
jutf7-1.0.0.jar
|
||||
log4j-1.2.17.jar
|
||||
netty-3.3.1.Final.jar
|
||||
protocols-api-1.6.4-.*.jar
|
||||
protocols-imap-1.6.4-.*.jar
|
||||
protocols-netty-1.6.4-.*.jar
|
||||
slf4j-api-.*.jar
|
||||
slf4j-log4j12-.*.jar
|
||||
|
||||
# Downloaded SMTP libraries
|
||||
subethasmtp-3.1.7.jar
|
||||
|
||||
# Downloaded JUnit libraries
|
||||
junit-4.8.1.jar
|
||||
|
||||
# Downloaded Mockito libraries
|
||||
mockito-core-2.0.31-beta.jar
|
||||
|
||||
# Downloaded jMock libraries
|
||||
cglib-nodep-2.2.3.jar
|
||||
hamcrest-core-1.3.jar
|
||||
hamcrest-library-1.3.jar
|
||||
hamcrest-unit-test-1.3.jar
|
||||
jmock-2.6.0.jar
|
||||
jmock-junit3-2.6.0.jar
|
||||
jmock-junit4-2.6.0.jar
|
||||
jmock-legacy-2.6.0.jar
|
||||
jmock-script-2.6.0.jar
|
||||
objenesis-1.0.jar
|
21
.tx/config
Normal file
@ -0,0 +1,21 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = ru_RU: ru, sv_SE: sv, tr_TR: tr, uk_UA: uk, zh_CN: zh
|
||||
|
||||
[I2P.plugin_i2pbote]
|
||||
file_filter = locale/messages_<lang>.po
|
||||
source_file = locale/messages_en.po
|
||||
source_lang = en
|
||||
minimum_perc = 40
|
||||
|
||||
[I2P.plugin_i2pbote_userguide]
|
||||
file_filter = src/main/webapp/html/userGuide_<lang>.html
|
||||
source_file = src/main/webapp/html/userGuide.html
|
||||
source_lang = en
|
||||
minimum_perc = 50
|
||||
|
||||
[I2P.plugin_i2pbote_faq]
|
||||
file_filter = src/main/webapp/html/FAQ_<lang>.html
|
||||
source_file = src/main/webapp/html/FAQ.html
|
||||
source_lang = en
|
||||
minimum_perc = 50
|
28
README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# I2P-Bote
|
||||
|
||||
I2P-Bote is a plugin for I2P that allows users to send and receive emails while preserving privacy. It does not need a mail server because emails are stored in a distributed hash table. They are automatically encrypted and digitally signed, which ensures no one but the intended recipient can read the email, and third parties cannot forge them.
|
||||
|
||||
**Features:**
|
||||
|
||||
* Themeable webmail interface
|
||||
* User interface translated in many languages
|
||||
* One-click creation of email accounts (called email identities)
|
||||
* Emails can be sent under a sender identity, or anonymously
|
||||
* ElGamal, Elliptic Curve, and NTRU Encryption
|
||||
* Encryption and signing is transparent, without the need to know about PGP
|
||||
* Delivery confirmation
|
||||
* Basic support for short recipient names
|
||||
* IMAP / SMTP
|
||||
|
||||
**Planned Features:**
|
||||
|
||||
* Custom folders
|
||||
* Sending and receiving via relays, similar to Mixmaster
|
||||
* Lots of small improvements
|
||||
|
||||
**More information**
|
||||
|
||||
The links below only work within I2P, i.e., make sure you are running I2P and your browser is using the proxy at localhost:4444.
|
||||
|
||||
* http://i2pbote.i2p I2P-Bote homepage
|
||||
* http://forum.i2p/viewforum.php?f=35 I2P-Bote forum
|
28
TODO
Normal file
@ -0,0 +1,28 @@
|
||||
User guide
|
||||
- Howto for IMAP/SMTP
|
||||
Email composition
|
||||
- "Include sent time" as an option, pre-filled with settings default
|
||||
Identities
|
||||
- Generate dests in background rather than needing a dedicated tab open
|
||||
IMAP/SMTP
|
||||
- "Force SSL" option
|
||||
- When disabled, users can connect with "insecure" or "STARTTLS"
|
||||
- When enabled, users can connect with "SSL"
|
||||
- Separate password cache (IMAP auth should not unlock webui)
|
||||
|
||||
Not-yet-implemented
|
||||
- Drafts folder
|
||||
- User-defined folders
|
||||
- Automatically disable timestamps when using mail routes
|
||||
- Random offset for fetch interval (#1360)
|
||||
- Per-identity settings (#1359)
|
||||
- Fetch interval
|
||||
- Mail route per-hop settings
|
||||
- Delay (#1361)
|
||||
- Fixed forward time
|
||||
- Traffic correlation countermeasures at relays
|
||||
- Mixing anonymity (minimum threshold on relay packets to send)
|
||||
- Constant traffic (test and dummy messages)
|
||||
- Balanced incoming/outgoing ratio
|
||||
- Packet padding
|
||||
- Retrieving email via relays
|
@ -1,20 +0,0 @@
|
||||
<%@ attribute name="address" required="true" description="The email address to display" %>
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
|
||||
<% jspContext.setAttribute("newline", "\n"); %>
|
||||
|
||||
<%-- If the address contains a name that is followed by an email destination in angle brackets, put a line break after the name --%>
|
||||
<c:set var="gtHtml" value="${fn:escapeXml('<')}"/>
|
||||
<c:set var="newlinePlusGt" value="${newline}${gtHtml}"/>
|
||||
<c:set var="formattedAddress" value="${fn:escapeXml(address)}"/>
|
||||
<c:set var="formattedAddress" value="${fn:replace(formattedAddress, gtHtml, newlinePlusGt)}"/>
|
||||
|
||||
<%-- if the address contains an email destination, use a textarea; otherwise just print it --%>
|
||||
<c:if test="${fn:length(formattedAddress) ge 512}">
|
||||
<textarea cols="64" rows="9" readonly="yes" wrap="soft" class="nobordertextarea">${formattedAddress}</textarea>
|
||||
</c:if>
|
||||
<c:if test="${fn:length(formattedAddress) lt 512}">
|
||||
${formattedAddress}
|
||||
</c:if>
|
@ -1,12 +0,0 @@
|
||||
<%@ attribute name="folderName" required="true" description="This is the folder directory and also the folder's display name" %>
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:set var="numEmails" value="${ib:getMailFolder(folderName).numElements}"/>
|
||||
<c:set var="numNew" value="${ib:getMailFolder(folderName).numNewEmails}"/>
|
||||
<a href="folder.jsp?path=${folderName}" title="${numEmails} emails total, ${numNew} new">
|
||||
<img src="images/folder.png"/>${folderName}
|
||||
</a>
|
||||
<c:if test="${numNew>0}">(${numNew})</c:if>
|
@ -1,17 +0,0 @@
|
||||
<%@ attribute name="text" required="true" description="The text to display" %>
|
||||
<%@ attribute name="width" required="false" description="The maximum number of characters in each line" %>
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
|
||||
<c:if test="${empty width}">
|
||||
<c:set var="width" value="64"/>
|
||||
</c:if>
|
||||
|
||||
<c:set var="length" value="${fn:length(text)}"/>
|
||||
<c:forEach var="i" begin="0" end="${length}" step="${width}">
|
||||
<c:if test="${i > 0}">
|
||||
<br/>
|
||||
</c:if>
|
||||
${fn:substring(text, i, i+64)}
|
||||
</c:forEach>
|
@ -1,316 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
|
||||
|
||||
<tlib-version>1.0</tlib-version>
|
||||
<short-name>i2pbote</short-name>
|
||||
<uri>I2pBoteTags</uri>
|
||||
|
||||
<tag>
|
||||
<name>sendEmail</name>
|
||||
<tag-class>i2p.bote.web.SendEmailTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
<attribute>
|
||||
<name>sender</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>recipient</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>subject</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>message</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>checkForMail</name>
|
||||
<tag-class>i2p.bote.web.CheckMailTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>formatPlainText</name>
|
||||
<tag-class>i2p.bote.web.FormatPlainTextTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
<attribute>
|
||||
<name>text</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>setEmailRead</name>
|
||||
<tag-class>i2p.bote.web.SetEmailReadTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
<attribute>
|
||||
<name>folder</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>messageId</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>read</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>quote</name>
|
||||
<tag-class>i2p.bote.web.QuoteTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
<attribute>
|
||||
<name>text</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>shortSenderName</name>
|
||||
<tag-class>i2p.bote.web.PrintShortSenderNameTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
<attribute>
|
||||
<name>sender</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>connect</name>
|
||||
<tag-class>i2p.bote.web.ConnectTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>localDestination</name>
|
||||
<tag-class>i2p.bote.web.LocalDestinationTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>peerInfo</name>
|
||||
<tag-class>i2p.bote.web.PeerInfoTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>message</name>
|
||||
<description>
|
||||
Same as fmt:message, except that message keys in
|
||||
the "en" locale translate to the message key itself.
|
||||
</description>
|
||||
<tag-class>i2p.bote.web.MessageTag</tag-class>
|
||||
<body-content>JSP</body-content>
|
||||
<attribute>
|
||||
<name>key</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>bundle</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>false</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>var</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>false</required>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<name>scope</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>false</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>param</name>
|
||||
<description>
|
||||
Same as fmt:param. Must be inside an ib:message tag.
|
||||
</description>
|
||||
<tag-class>i2p.bote.web.ParamTag</tag-class>
|
||||
<body-content>scriptless</body-content>
|
||||
<attribute>
|
||||
<name>value</name>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
<required>true</required>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<name>saveConfiguration</name>
|
||||
<description>
|
||||
Saves the configuration to the config file.
|
||||
</description>
|
||||
<tag-class>i2p.bote.web.SaveConfigurationTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
</tag>
|
||||
|
||||
<function>
|
||||
<name>getNetworkStatus</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.network.NetworkStatus getNetworkStatus()
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getIdentities</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.email.Identities getIdentities()
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>saveIdentity</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean saveIdentity(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>deleteIdentity</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean deleteIdentity(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getAddressBook</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.addressbook.AddressBook getAddressBook()
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>saveContact</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean saveContact(java.lang.String, java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>deleteContact</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean deleteContact(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getContact</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.addressbook.Contact getContact(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>isCheckingForMail</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean isCheckingForMail()
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>newMailReceived</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
boolean newMailReceived()
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getMailFolder</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.EmailFolder getMailFolder(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getEmail</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.email.Email getEmail(java.lang.String, java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getOneLocalRecipient</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
java.lang.String getOneLocalRecipient(i2p.bote.email.Email)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>deleteEmail</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
java.lang.boolean deleteEmail(java.lang.String, java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>extractName</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
java.lang.String extractName(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>extractEmailDestination</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
i2p.bote.email.EmailDestination extractEmailDestination(java.lang.String)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<function>
|
||||
<name>getRecipients</name>
|
||||
<function-class>i2p.bote.web.JSPHelper</function-class>
|
||||
<function-signature>
|
||||
java.util.Map getRecipients(java.util.Map)
|
||||
</function-signature>
|
||||
</function>
|
||||
|
||||
<tag-file>
|
||||
<name>printWithLineBreaks</name>
|
||||
<path>/WEB-INF/tags/printWithLineBreaks.tag</path>
|
||||
</tag-file>
|
||||
|
||||
<tag-file>
|
||||
<name>folderLink</name>
|
||||
<path>/WEB-INF/tags/folderLink.tag</path>
|
||||
</tag-file>
|
||||
|
||||
<tag-file>
|
||||
<name>address</name>
|
||||
<path>/WEB-INF/tags/address.tag</path>
|
||||
</tag-file>
|
||||
|
||||
</taglib>
|
@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||
<display-name>i2pbote</display-name>
|
||||
|
||||
<!-- precompiled servlets -->
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<listener>
|
||||
<listener-class>i2p.bote.web.ServiceInitializer</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>CharsetFilter</filter-name>
|
||||
<filter-class>i2p.bote.web.CharsetFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>requestEncoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>CharsetFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
</web-app>
|
@ -1,122 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%--
|
||||
This page behaves differently depending on the "search" boolean parameter.
|
||||
If search is true, the user can select contacts and add them as recipients.
|
||||
If search is false, the user can view and edit the address book.
|
||||
--%>
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<ib:message key="Address Book" var="title" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="main">
|
||||
<c:set var="contacts" value="${ib:getAddressBook().all}"/>
|
||||
|
||||
<h2>
|
||||
<c:if test="${!param.search}"><ib:message key="Private Address Book"/></c:if>
|
||||
<c:if test="${param.search && !empty contacts}"><ib:message key="Select One or More Entries"/></c:if>
|
||||
</h2>
|
||||
|
||||
<c:if test="${empty contacts}">
|
||||
The address book is empty.
|
||||
</c:if>
|
||||
|
||||
<div class="addressbook">
|
||||
|
||||
<c:if test="${param.search}">
|
||||
<form action="newEmail.jsp" method="POST">
|
||||
<c:forEach var="parameter" items="${param}">
|
||||
<input type="hidden" name="${parameter.key}" value="${parameter.value}"/>
|
||||
</c:forEach>
|
||||
</c:if>
|
||||
|
||||
<table>
|
||||
<c:if test="${!empty contacts}">
|
||||
<tr>
|
||||
<c:if test="${param.search}"><th style="width: 10px;"></th></c:if>
|
||||
<th><ib:message key="Name"/></th>
|
||||
<th><ib:message key="Email Destination"/></th>
|
||||
<th style="width: 20px; padding: 0px"></th>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${contacts}" var="contact" varStatus="loopStatus">
|
||||
<tr>
|
||||
<c:if test="${param.search}">
|
||||
<td>
|
||||
<input type="checkbox" name="selectedContact" value="${contact.name} <${contact.destination}>"/>
|
||||
</td>
|
||||
</c:if>
|
||||
<td style="width: 100px;">
|
||||
<div class="ellipsis">
|
||||
<c:if test="${!param.search}">
|
||||
<a href="editContact.jsp?new=false&destination=${contact.destination}&name=${contact.name}">
|
||||
</c:if>
|
||||
${contact.name}
|
||||
<c:if test="${!param.search}">
|
||||
</a>
|
||||
</c:if>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 100px;">
|
||||
<div class="ellipsis">
|
||||
${contact.destination}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<c:if test="${!param.search}">
|
||||
<a href="deleteContact.jsp?destination=${contact.destination}"><img src="images/delete.png" alt="<ib:message key='Delete'/>" title='<ib:message key='Delete this contact'/>'/></a>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p/>
|
||||
<table>
|
||||
<c:if test="${!param.search}">
|
||||
<tr><td>
|
||||
<form action="editContact.jsp?new=true" method="POST">
|
||||
<button type="submit" value="New"><ib:message key="New Contact"/></button>
|
||||
</form>
|
||||
</td></tr>
|
||||
</c:if>
|
||||
<c:if test="${param.search}">
|
||||
<tr><td>
|
||||
<button type="submit" value="New"><ib:message key="Add Recipients"/></button>
|
||||
</td></tr>
|
||||
</c:if>
|
||||
</table>
|
||||
|
||||
<c:if test="${param.search}">
|
||||
</form>
|
||||
</c:if>
|
||||
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,97 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<jsp:include page="getStatus.jsp"/>
|
||||
|
||||
<c:if test="${param.checkMail == 1}">
|
||||
<ib:checkForMail/>
|
||||
</c:if>
|
||||
|
||||
<c:if test="${ib:isCheckingForMail()}">
|
||||
<c:set var="checkingForMail" value="true"/>
|
||||
</c:if>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="i2pbote.css" />
|
||||
<c:if test="${checkingForMail}">
|
||||
<meta http-equiv="refresh" content="20;url=buttonFrame.jsp" />
|
||||
</c:if>
|
||||
</head>
|
||||
|
||||
<body style="background-color: transparent; margin: 0px;">
|
||||
|
||||
<c:set var="disable" value=""/>
|
||||
<c:if test="${connStatus == DELAY}">
|
||||
<c:set var="disable" value="disabled="disabled""/>
|
||||
</c:if>
|
||||
|
||||
<table><tr>
|
||||
<td>
|
||||
<c:if test="${checkingForMail}">
|
||||
<div class="checkmail">
|
||||
<img src="images/wait.gif"/>Checking for mail...
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${!checkingForMail}">
|
||||
<div class="checkmail">
|
||||
<c:choose>
|
||||
<c:when test="${empty ib:getIdentities().all}">
|
||||
<c:set var="url" value="noIdentities.jsp"/>
|
||||
<c:set var="frame" value="target="_parent""/>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<c:set var="link" value="buttonFrame.jsp"/>
|
||||
<c:set var="frame" value=""/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
<form action="${url}" ${frame} method="GET">
|
||||
<input type="hidden" name="checkMail" value="1"/>
|
||||
<button type="submit" value="<ib:message key="Check Mail"/>" ${disable}>Check Mail</button>
|
||||
</form>
|
||||
</div>
|
||||
<c:if test="${ib:newMailReceived()}">
|
||||
<script language="Javascript">
|
||||
// If inbox is being displayed, reload so the new email(s) show
|
||||
if (parent.document.getElementById('inboxFlag'))
|
||||
parent.location.reload();
|
||||
</script>
|
||||
</c:if>
|
||||
</c:if>
|
||||
</td>
|
||||
<td>
|
||||
<form action="newEmail.jsp" target="_top" method="GET">
|
||||
<button type="submit" value="<ib:message key="New"/>" ${disable}>New</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr></table>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,80 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${param.new}">
|
||||
<ib:message key="New Contact" var="title"/>
|
||||
<c:set var="title" value="${title}" scope="request"/>
|
||||
<ib:message key="Add" var="action"/>
|
||||
<c:set var="commitAction" value="${action}"/>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<ib:message key="Edit Contact" var="title"/>
|
||||
<c:set var="title" value="${title}" scope="request"/>
|
||||
<ib:message key="Add" var="action"/>
|
||||
<c:set var="commitAction" value="${action}"/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="main">
|
||||
<form name="form" action="saveContact.jsp" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><ib:message key="Email Destination"/></div>
|
||||
<c:if test="${empty param.destination}">
|
||||
<div style="font-size: 0.8em;"><ib:message key="(required field, must be 512 characters)"/></div>
|
||||
</c:if>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" size="80" name="destination" value="${param.destination}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><ib:message key="Name:"/></div>
|
||||
<div style="font-size: 0.8em;"><ib:message key="(required field)"/></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" size="40" name="name" value="${param.name}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="hidden" name="destination" value="${param.destination}"/>
|
||||
<input type="submit" name="action" value="${commitAction}"/>
|
||||
<input type="submit" name="action" value="<ib:message key="Cancel"/>"/>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" language="JavaScript">
|
||||
document.forms['form'].elements['name'].focus();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,109 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${param.new}">
|
||||
<ib:message key="New Email Identity" var="title"/>" scope="request"/>
|
||||
<ib:message key="Create" var="commitAction"/>"/>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<ib:message key="Edit Email Identity" var="title"/>
|
||||
<ib:message key="Save" var="commitAction"/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="errorMessage">
|
||||
${fn:escapeXml(param.errorMessage)}
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<form name="form" action="saveIdentity.jsp">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><ib:message key="Public Name:"/></div>
|
||||
<div style="font-size: 0.8em;"><ib:message key="(required field, shown to recipients)"/></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" size="40" name="publicName" value="${param.publicName}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><ib:message key="Description:"/></div>
|
||||
<div style="font-size: 0.8em;"><ib:message key="(optional, kept private)"/></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" size="40" name="description" value="${param.description}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><ib:message key="Email Address:"/></div>
|
||||
<div style="font-size: 0.8em;"><ib:message key="(optional)"/></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" size="40" name="emailAddress" value="${param.emailAddress}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<c:if test="${!empty param.key}">
|
||||
<tr>
|
||||
<td style="font-weight: bold; vertical-align: top;">
|
||||
<ib:message key="Email Destination:"/>
|
||||
</td>
|
||||
<td>
|
||||
<textarea cols="64" rows="9" readonly="yes" wrap="soft" class="destinationtextarea">${param.key}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight: bold; vertical-align: top;">
|
||||
<ib:message key="Default Identity:"/>
|
||||
</td>
|
||||
<td>
|
||||
<c:if test="${param.isDefault}">
|
||||
<c:set var="checked" value="checked"/>
|
||||
</c:if>
|
||||
<input type="checkbox" name="isDefault" ${checked}/>
|
||||
</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
</table>
|
||||
<input type="hidden" name="key" value="${param.key}"/>
|
||||
<input type="submit" name="action" value="${commitAction}"/>
|
||||
<input type="submit" name="action" value="<ib:message key='Cancel'/>"/>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" language="JavaScript">
|
||||
document.forms['form'].elements['publicName'].focus();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,88 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:set var="title" value="${param.path}" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<c:set var="folderName" value="Inbox"/>
|
||||
<c:if test="${folderName == 'Inbox'}">
|
||||
<div id="inboxFlag"></div>
|
||||
</c:if>
|
||||
|
||||
<div class="main">
|
||||
<div class="folder">
|
||||
<table>
|
||||
<tr>
|
||||
<th style="width: 100px;"><ib:message key="From"/></th>
|
||||
<th style="width: 100px;"><ib:message key="To"/></th>
|
||||
<th style="width: 150px;"><ib:message key="Subject"/></th>
|
||||
<th style="width: 100px;"><ib:message key="Date"/></th>
|
||||
<th style="width: 20px;"></th>
|
||||
</tr>
|
||||
<c:forEach items="${ib:getMailFolder(folderName).elements}" var="email">
|
||||
<tr>
|
||||
<c:set var="sender" value="${email.sender}"/>
|
||||
<c:if test="${empty sender}">
|
||||
<ib:message key="Anonymous" var="sender"/>
|
||||
</c:if>
|
||||
|
||||
<c:set var="recipient" value="${ib:getOneLocalRecipient(email)}"/>
|
||||
|
||||
<c:set var="date" value="${email.sentDate}"/>
|
||||
<c:if test="${empty date}">
|
||||
<ib:message key="Unknown" var="date"/>"/>
|
||||
</c:if>
|
||||
|
||||
<c:set var="subject" value="${email.subject}"/>
|
||||
<c:if test="${empty subject}">
|
||||
<ib:message key="(No subject)" var="subject"/>
|
||||
</c:if>
|
||||
|
||||
<c:set var="mailUrl" value="showEmail.jsp?folder=${folderName}&messageID=${email.messageID}"/>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${email.new}"><c:set var="fontWeight" value="bold"/></c:when>
|
||||
<c:otherwise><c:set var="fontWeight" value="normal"/></c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
<td><div class="ellipsis"><a href="${mailUrl}" style="font-weight: ${fontWeight}">${fn:escapeXml(sender)}</a></div></td>
|
||||
<td><div class="ellipsis"><a href="${mailUrl}" style="font-weight: ${fontWeight}">${fn:escapeXml(recipient)}</a></div></td>
|
||||
<td><div class="ellipsis"><a href="${mailUrl}" style="font-weight: ${fontWeight}">${fn:escapeXml(subject)}</a></div></td>
|
||||
<td><a href="${mailUrl}" style="font-weight: ${fontWeight}">${fn:escapeXml(date)}</a></td>
|
||||
<td>
|
||||
<a href="deleteEmail.jsp?folder=${folderName}&messageID=${email.messageID}">
|
||||
<img src="images/delete.png" alt="<ib:message key='Delete'/>" title="<ib:message key='Delete this email'/>"/></a>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,99 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<fmt:requestEncoding value="UTF-8"/>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="i2pbote.css" />
|
||||
<link rel="icon" type="image/png" href="images/favicon.png" />
|
||||
<c:if test="${!empty title}">
|
||||
<title>${title} <ib:message key="- I2P-Bote"/></title>
|
||||
</c:if>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="titlebar" style="cursor:pointer" onclick="document.location='.'">
|
||||
<div class="title"><ib:message key="I2P-Bote"/></div>
|
||||
<br/>
|
||||
<div class="subtitle"><ib:message key="Secure Distributed Email"/></div>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<iframe src="buttonFrame.jsp" width="100%" height="40px" scrolling="no" frameborder="0" allowtransparency="true"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<h2><ib:message key="Folders"/></h2>
|
||||
<ib:message key="Inbox" var="folderName"/><ib:folderLink folderName="${folderName}"/><br/>
|
||||
<img src="images/folder.png"/><ib:message key="Outbox"/><br/>
|
||||
<img src="images/folder.png"/><ib:message key="Sent"/><br/>
|
||||
<img src="images/folder.png"/><ib:message key="Drafts"/><br/>
|
||||
<img src="images/folder.png"/><ib:message key="Trash"/><br/>
|
||||
<hr/>
|
||||
<img src="images/folder.png"/>User_created_Folder_1<br/>
|
||||
<img src="images/folder.png"/>User_created_Folder_2<br/>
|
||||
<img src="images/folder.png"/>User_created_Folder_3<br/>
|
||||
<hr/>
|
||||
<ib:message key="Manage Folders"/>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<h2><ib:message key="Addresses"/></h2>
|
||||
<a href="identities.jsp"><ib:message key="Identities"/></a><br/>
|
||||
<a href="addressBook.jsp"><ib:message key="Address Book"/></a><br/>
|
||||
Public Address Directory<br/>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<h2><ib:message key="Configuration"/></h2>
|
||||
<a href="settings.jsp"><ib:message key="Settings"/></a><br/>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<h2><a href="network.jsp"><ib:message key="Network Status"/></a></h2>
|
||||
<iframe src="statusFrame.jsp" width="100%" height="40px" scrolling="no" frameborder="0" allowtransparency="true"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="menubox">
|
||||
<h2><ib:message key="Help"/></h2>
|
||||
<ib:message key="User Guide"/><br/>
|
||||
<a href="about.jsp"><ib:message key="About"/></a><br/>
|
||||
</div>
|
||||
|
||||
<div class="infoMessage">
|
||||
${fn:escapeXml(param.infoMessage)}
|
||||
</div>
|
||||
|
||||
<div class="errorMessage">
|
||||
${fn:escapeXml(param.errorMessage)}
|
||||
</div>
|
@ -1,396 +0,0 @@
|
||||
/* Based on the router console css */
|
||||
|
||||
body {
|
||||
margin: 15px 0 0 10px;
|
||||
padding: 0em;
|
||||
text-align: center;
|
||||
background: #eef;
|
||||
color: #000;
|
||||
font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.titlebar {
|
||||
width: 800px;
|
||||
margin: 0px 20px 20px 240px;
|
||||
background-color: #fff;
|
||||
color: #310;
|
||||
padding: 0 15px 15px 25px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #001;
|
||||
text-align: center;
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
||||
white-space: normal;
|
||||
background: #ddf url('images/lightbluetile.png');
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font: normal bold 20pt/120% 'Lucida Sans Unicode', 'Bitstream Vera Sans', Verdana, Tahoma, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.15em;
|
||||
text-shadow: 0px 0px 1px rgba(0, 0, 148, 0.9);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 8pt;
|
||||
color: #cf0606;
|
||||
letter-spacing: 5pt;
|
||||
text-shadow: 0px 0px 1px rgba(148, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.checkmail {
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.menubox {
|
||||
float: left;
|
||||
width: 175px;
|
||||
margin: 0px 0px 10px 10px;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
border: 1px solid #000033;
|
||||
background: #ddf url('images/lightbluetile.png');
|
||||
color: #000;
|
||||
font-size: 8pt;
|
||||
clear: left;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
||||
}
|
||||
|
||||
.menubox a:link, .menubox a:visited {
|
||||
text-shadow: 0px 0px 1px rgba(0, 0, 32, 0.5);
|
||||
}
|
||||
|
||||
.menubox a:hover {
|
||||
text-shadow: 0px 0px 0.5px rgba(255, 255, 255, 0.7);
|
||||
color: #f60;
|
||||
}
|
||||
|
||||
.menubox h2 {
|
||||
font-size: 12pt;
|
||||
color: #001;
|
||||
letter-spacing: 0.05em;
|
||||
text-shadow: 0px 0px 1px rgba(0, 0, 64, 0.5);
|
||||
wordwrap: none;
|
||||
}
|
||||
|
||||
.statusbox {
|
||||
font-size: 8pt;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 800px;
|
||||
margin: 0px 20px 20px 240px;
|
||||
padding: 0 15px 15px 25px;
|
||||
background: #eef;
|
||||
font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
text-align: left;
|
||||
color: #001;
|
||||
border: 1px solid #000033;
|
||||
background: #ddf url('images/lightbluetile.png');
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
||||
}
|
||||
|
||||
.emailtext {
|
||||
width: 800px;
|
||||
margin: 0px 20px 20px 240px;
|
||||
padding: 0 15px 15px 25px;
|
||||
background: #eef;
|
||||
font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
text-align: left;
|
||||
color: #001;
|
||||
border: 1px solid #000033;
|
||||
background: #cce2ff;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
||||
}
|
||||
|
||||
.infoMessage {
|
||||
margin: 0px 20px 5px 240px;
|
||||
text-align: left;
|
||||
color: green;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
margin: 0px 20px 5px 240px;
|
||||
text-align: left;
|
||||
color: red;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #900;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: #007;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #606;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #f60;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #f93;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
button, button:visited {
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
border: 1px outset #999;
|
||||
padding: 1px 3px;
|
||||
background: #ddf !important;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
margin: 0 1px;
|
||||
text-align: center;
|
||||
min-width: 80px;
|
||||
-moz-box-shadow: inset 0px 2px 8px 0px #fff;
|
||||
color: #006;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border: 1px solid #f60;
|
||||
background: #f60 !important;
|
||||
color: #fff;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #fff;
|
||||
}
|
||||
|
||||
button:active {
|
||||
border: 1px solid #f60;
|
||||
background: #001 !important;
|
||||
color: #f60;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #f60;
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
border: 1px outset #999;
|
||||
background: #ddf !important;
|
||||
color: #666;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #999;
|
||||
}
|
||||
|
||||
.underline {
|
||||
border-bottom: 1px solid #000022;
|
||||
padding: 5px 0px 5px 0px;
|
||||
margin: 0px 0px 10px 0px;
|
||||
}
|
||||
|
||||
input {
|
||||
background: #eef;
|
||||
color: #001;
|
||||
margin: 5px 10px 5px 10px;
|
||||
padding: 4px 2px;
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
border: 1px solid #001;
|
||||
text-decoration: none;
|
||||
min-width: 110px;
|
||||
}
|
||||
|
||||
input, input:visited {
|
||||
border: 1px outset #999;
|
||||
background: #ddf;
|
||||
color: #001;
|
||||
margin: 5px;
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
padding: 1px 2px;
|
||||
text-decoration: none;
|
||||
min-width: 110px;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
-moz-box-shadow: inset 0px 2px 8px 0px #fff;
|
||||
color: #006;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
input:hover {
|
||||
background: #f60;
|
||||
color: #fff;
|
||||
border: 1px solid #f60;
|
||||
opacity: 1.0;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #fff;
|
||||
}
|
||||
|
||||
input:active {
|
||||
background: #002;
|
||||
color: #f60;
|
||||
border: 1px solid #f60;
|
||||
opacity: 1.0;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #f60;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
background: #eef;
|
||||
color: #001;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
border: 1px solid #001;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.widetextfield {
|
||||
width: 100%;
|
||||
background: #eef;
|
||||
color: #001;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
border: 1px solid #001;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
input checkbox {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background: #eef;
|
||||
color: #003;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
min-height: 100px;
|
||||
border: 1px solid #001;
|
||||
}
|
||||
|
||||
.nobordertextarea {
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
background: #eef;
|
||||
background-color: transparent;
|
||||
color: #003;
|
||||
font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
min-height: 100px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.destinationtextarea {
|
||||
width: 100%;
|
||||
background: #eef;
|
||||
background-color: transparent;
|
||||
color: #003;
|
||||
border: none;
|
||||
font: 8pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
submit {
|
||||
background: #f00;
|
||||
color: #eef;
|
||||
margin: 10px 2px 10px 0;
|
||||
padding: 2px;
|
||||
font-family: "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
border: 1px solid #001;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
select {
|
||||
background: #eef;
|
||||
color: #003;
|
||||
padding: 2px;
|
||||
margin: 5px;
|
||||
border: 1px solid #001;
|
||||
font: 9pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.folder table {
|
||||
table-layout: fixed;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.identities table {
|
||||
table-layout: fixed;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.identities td, .identities th {
|
||||
vertical-align: top;
|
||||
padding: 0px 30px 0px 0px;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.addressbook table {
|
||||
table-layout: fixed;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.addressbook td, .addressbook th {
|
||||
vertical-align: middle;
|
||||
padding: 0px 30px 0px 0px;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ellipsis
|
||||
{
|
||||
line-height: 1.2em;
|
||||
height: 1.2em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
-o-text-overflow: ellipsis;
|
||||
-moz-binding: url(moz_fix2.xml#ellipsis);
|
||||
}
|
||||
|
||||
.moz-ellipsis > DIV:first-child
|
||||
{
|
||||
float: left;
|
||||
margin-right: -26px;
|
||||
}
|
||||
|
||||
.moz-ellipsis > DIV + DIV
|
||||
{
|
||||
float: right;
|
||||
margin-top: -1.2em;
|
||||
background: url('images/lightbluefade.png');
|
||||
padding-left: 26px;
|
||||
}
|
||||
|
||||
.moz-ellipsis > DIV + DIV::after
|
||||
{
|
||||
background: url('images/lightbluetile.png');
|
||||
content: '...';
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:set var="title" value="Identities" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="infoMessage">
|
||||
${param.infoMessage}
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<h2>
|
||||
<ib:message key="Email Identities"/>
|
||||
</h2>
|
||||
|
||||
<c:set var="identities" value="${ib:getIdentities().all}"/>
|
||||
<c:if test="${empty identities}">
|
||||
<ib:message key="No email identities are defined."/>
|
||||
</c:if>
|
||||
|
||||
<div class="identities">
|
||||
<table>
|
||||
<c:if test="${!empty identities}">
|
||||
<tr>
|
||||
<th style="width: 20px;"><ib:message key="Def."/></th>
|
||||
<th><ib:message key="Public Name"/></th>
|
||||
<th><ib:message key="Description"/></th>
|
||||
<th><ib:message key="Email Address"/></th>
|
||||
<th><ib:message key="Key"/></th>
|
||||
<th style="width: 20px; padding: 0px"></th>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${identities}" var="identity">
|
||||
<tr>
|
||||
<td style="width: 20px; text-align: right;">
|
||||
<c:if test="${identity.default}">
|
||||
<img src="images/asterisk.png"/>
|
||||
</c:if>
|
||||
</td>
|
||||
<td style="width: 100px;">
|
||||
<div class="ellipsis">
|
||||
<a href="editIdentity.jsp?new=false&key=${identity.key}&publicName=${identity.publicName}&description=${identity.description}&emailAddress=${identity.emailAddress}&isDefault=${identity.default}">
|
||||
${identity.publicName}
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 150px;">
|
||||
<div class="ellipsis">
|
||||
${identity.description}
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 150px;">
|
||||
<div class="ellipsis">
|
||||
${identity.emailAddress}
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 100px;">
|
||||
<div class="ellipsis">
|
||||
${identity.key}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="deleteIdentity.jsp?key=${identity.key}"><img src="images/delete.png" alt="<ib:message key='Delete'/>" title="<ib:message key='Delete this identity'/>"/></a>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p/>
|
||||
<form action="editIdentity.jsp?new=true" method="POST">
|
||||
<button type="submit" value="<ib:message key='New'/>"><ib:message key="New Identity"/></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
Before Width: | Height: | Size: 298 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 852 B |
Before Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 794 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 803 B |
Before Width: | Height: | Size: 1.3 KiB |
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<binding id="ellipsis" applyauthorstyles="false">
|
||||
<implementation>
|
||||
<constructor><![CDATA[
|
||||
(function(block){
|
||||
setTimeout(function(){
|
||||
block.style.mozBinding = '';
|
||||
var t = document.createElement('DIV');
|
||||
block.appendChild(t);
|
||||
block.appendChild(document.createElement('DIV'));
|
||||
while (block.firstChild != t)
|
||||
t.appendChild(block.firstChild);
|
||||
block.className = block.className + ' moz-ellipsis';
|
||||
}, 0);
|
||||
})(this);
|
||||
]]></constructor>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
@ -1,158 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${param.action eq 'send'}">
|
||||
<jsp:forward page="sendEmail.jsp"/>
|
||||
</c:when>
|
||||
<c:when test="${fn:startsWith(param.action, 'lookup')}">
|
||||
<jsp:forward page="addressBook.jsp">
|
||||
<jsp:param name="search" value="true"/>
|
||||
<jsp:param name="action" value=""/>
|
||||
</jsp:forward>
|
||||
</c:when>
|
||||
</c:choose>
|
||||
|
||||
<ib:message key="New Email" var="title"scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="main">
|
||||
<form action="newEmail.jsp" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<ib:message key="From:"/>
|
||||
</td>
|
||||
<td>
|
||||
<select name="sender">
|
||||
<option value="anonymous">Anonymous</option>
|
||||
<c:forEach items="${ib:getIdentities().all}" var="identity">
|
||||
<c:set var="selected" value=""/>
|
||||
<c:if test="${fn:contains(param.sender, identity.key)}">
|
||||
<c:set var="selected" value=" selected"/>
|
||||
</c:if>
|
||||
<c:if test="${empty param.sender && identity.default}">
|
||||
<c:set var="selected" value=" selected"/>
|
||||
</c:if>
|
||||
<option value="${identity.publicName} <${identity.key}>"${selected}>
|
||||
${identity.publicName}
|
||||
<c:if test="${!empty identity.description}"> - ${identity.description}</c:if>
|
||||
</option>
|
||||
</c:forEach>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<c:set var="maxRecipientIndex" value="-1"/>
|
||||
<c:forEach var="parameter" items="${ib:getRecipients(param)}">
|
||||
<c:set var="isRecipient" value="${fn:startsWith(parameter.key, 'recipient') and !fn:contains(parameter.key, 'Type')}"/>
|
||||
<c:if test="${isRecipient && !empty parameter.value}">
|
||||
<c:set var="recipientField" value="${parameter.key}"/>
|
||||
<c:set var="recipient" value="${parameter.value}"/>
|
||||
<c:set var="recipientIndex" value="${fn:substringAfter(recipientField, 'recipient')}"/>
|
||||
<c:if test="${recipientIndex gt maxRecipientIndex}">
|
||||
<c:set var="maxRecipientIndex" value="${recipientIndex}"/>
|
||||
</c:if>
|
||||
<tr><td>
|
||||
<c:set var="recipientTypeField" value="recipientType${recipientIndex}"/>
|
||||
<c:set var="recipientType" value="${param[recipientTypeField]}"/>
|
||||
<select name="${recipientTypeField}">
|
||||
<c:set var="toSelected" value="${recipientType eq 'to' ? ' selected' : ''}"/>
|
||||
<c:set var="ccSelected" value="${recipientType eq 'cc' ? ' selected' : ''}"/>
|
||||
<c:set var="bccSelected" value="${recipientType eq 'bcc' ? ' selected' : ''}"/>
|
||||
<c:set var="replytoSelected" value="${recipientType eq 'replyto' ? ' selected' : ''}"/>
|
||||
<option value="to"${toSelected}><ib:message key="To:"/></option>
|
||||
<option value="cc"${ccSelected}><ib:message key="CC:"/></option>
|
||||
<option value="bcc"${bccSelected}><ib:message key="BCC:"/></option>
|
||||
<option value="replyto"${replytoSelected}><ib:message key="Reply To:"/></option>
|
||||
</select>
|
||||
</td><td>
|
||||
<input type="text" size="80" name="${recipientField}" value="${recipient}"/>
|
||||
</td></tr>
|
||||
</c:if>
|
||||
</c:forEach>
|
||||
<c:if test="${!empty param.selectedContact}">
|
||||
<c:forEach var="destination" items="${paramValues.selectedContact}">
|
||||
<c:set var="maxRecipientIndex" value="${maxRecipientIndex+1}"/>
|
||||
<tr><td>
|
||||
<select name="recipientType${maxRecipientIndex}">
|
||||
<option value="to"><ib:message key="To:"/></option>
|
||||
<option value="cc"><ib:message key="CC:"/></option>
|
||||
<option value="bcc"><ib:message key="BCC:"/></option>
|
||||
<option value="replyto"><ib:message key="Reply To:"/></option>
|
||||
</select>
|
||||
</td><td>
|
||||
<input type="text" size="80" name="recipient${maxRecipientIndex}" value="${destination}"/>
|
||||
</td></tr>
|
||||
</c:forEach>
|
||||
</c:if>
|
||||
<c:set var="maxRecipientIndex" value="${maxRecipientIndex+1}"/>
|
||||
<tr><td>
|
||||
<select name="recipientType${maxRecipientIndex}">
|
||||
<option value="to"><ib:message key="To:"/></option>
|
||||
<option value="cc"><ib:message key="CC:"/></option>
|
||||
<option value="bcc"><ib:message key="BCC:"/></option>
|
||||
<option value="replyto"><ib:message key="Reply To:"/></option>
|
||||
</select>
|
||||
</td><td>
|
||||
<input class="widetextfield" type="text" size="80" name="recipient${maxRecipientIndex}"/>
|
||||
</td></tr>
|
||||
|
||||
<tr>
|
||||
<td/>
|
||||
<td style="text-align: right;">
|
||||
<button type="submit" name="action" value="addRecipient" disabled="disabled">+</button>
|
||||
<button type="submit" name="action" value="lookup0"><ib:message key="Addr. Book..."/></button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><br/><ib:message key="Subject:"/></td>
|
||||
<td><input class="widetextfield" type="text" size="80" name="subject" value="${param.subject}"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><br/><ib:message key="Message:"/></td>
|
||||
<td>
|
||||
<textarea rows="30" cols="80" name="message"><c:if test="${!empty param.quoteMsgId}">
|
||||
<%-- The following lines are not indented because the indentation would show up as blank chars on the textarea --%>
|
||||
<c:set var="origEmail" value="${ib:getEmail(param.quoteMsgFolder, param.quoteMsgId)}"/>
|
||||
<ib:shortSenderName sender="${origEmail.sender}"/> wrote:
|
||||
<ib:quote text="${origEmail.text}"/></c:if><c:if test="${empty param.quoteMsgId}">${param.message}</c:if></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=3 align="center">
|
||||
<button type="submit" name="action" value="send"><ib:message key="Send"/></button>
|
||||
<button type="submit" name="action" disabled="disabled"><ib:message key="Save"/></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,63 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<c:set var="title" value="No Identity" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="main">
|
||||
<h2>No Email Identity Defined</h2>
|
||||
<p>
|
||||
In order to receive email from other people, you need to create an email identity
|
||||
first.
|
||||
</p><p>
|
||||
This is similar to traditional email where you first have to set up an email account
|
||||
with an email provider. The difference is that in I2P-Bote, there is no provider that
|
||||
can read all your email because I2P-Bote stores all emails encrypted on the network.
|
||||
</p><p>
|
||||
I2P-Bote automatically decrypts emails sent to you, using the email identity you
|
||||
created.
|
||||
</p><p>
|
||||
An email identity has a secret key, and a public key. Anybody who has the secret key
|
||||
can download and decrypt your emails, so you should never give it to anybody. The
|
||||
public key, on the other hand, allows people to send email to you. Think of it as
|
||||
the equivalent of a traditional email address. Give it to everybody you want to be
|
||||
able to contact you, or make it public.
|
||||
</p><p>
|
||||
[TODO paragraph about spam, HashCash].
|
||||
</p><p>
|
||||
You will find that email identities are long combinations of numbers and letters,
|
||||
and that they are impossible to memorize. I2P-Bote lets you assign an email address
|
||||
to an email identity to make it easier for you and your contacts to remember.
|
||||
</p><p>
|
||||
[TODO name attribute, address attribute].
|
||||
The public addressbook should not be 100% trusted. Only destination keys are secure.
|
||||
</p><p>
|
||||
[TODO private address book, address directory].
|
||||
<form action="editIdentity.jsp?new=true" method="POST">
|
||||
<button type="submit" value="New">Create a New Email Identity</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,55 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:if test="${param.action == 'Cancel'}">
|
||||
<jsp:forward page="addressBook.jsp"/>
|
||||
</c:if>
|
||||
|
||||
<c:choose>
|
||||
<c:when test="${empty param.destination}">
|
||||
<ib:message key="Please fill in the Destination field." var="errorMessage"/>
|
||||
</c:when>
|
||||
<c:when test="${empty param.name}">
|
||||
<ib:message key="Please fill in the Name field." var="errorMessage"/>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<c:set var="errorMessage" value="${ib:saveContact(param.destination, param.name)}"/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
||||
<c:if test="${empty errorMessage}">
|
||||
<ib:message key="The contact has been saved." var="infoMessage"/>
|
||||
<jsp:forward page="addressBook.jsp">
|
||||
<jsp:param name="infoMessage" value="${infoMessage}"/>
|
||||
</jsp:forward>
|
||||
</c:if>
|
||||
<c:if test="${!empty errorMessage}">
|
||||
<jsp:forward page="editContact.jsp">
|
||||
<jsp:param name="errorMessage" value="${errorMessage}"/>
|
||||
</jsp:forward>
|
||||
</c:if>
|
@ -1,58 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<ib:message key="Settings" var="title" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="main">
|
||||
<h2>
|
||||
<ib:message key="Settings"/>
|
||||
</h2>
|
||||
<br/>
|
||||
|
||||
<jsp:useBean id="jspHelperBean" class="i2p.bote.web.JSPHelper"/>
|
||||
<c:set var="configuration" value="${jspHelperBean.configuration}"/>
|
||||
<c:if test="${param.action eq 'save'}">
|
||||
<jsp:setProperty name="configuration" property="autoMailCheckEnabled" value="${param.autoMailCheckEnabled eq 'on' ? 'true' : 'false'}"/>
|
||||
<jsp:setProperty name="configuration" property="mailCheckInterval" value="${param.mailCheckInterval}"/>
|
||||
<ib:saveConfiguration/>
|
||||
</c:if>
|
||||
|
||||
<form action="settings.jsp" method="post">
|
||||
<input type="hidden" name="action" value="save"/>
|
||||
|
||||
<c:set var="autoMailCheckEnabled" value="${jspHelperBean.configuration.autoMailCheckEnabled}"/>
|
||||
<c:set var="checked" value="${autoMailCheckEnabled ? ' checked' : ''}"/>
|
||||
<input type="checkbox"${checked} name="autoMailCheckEnabled"/>Check for mail every
|
||||
<input type="text" name="mailCheckInterval" size="3" value="${configuration.mailCheckInterval}"/> minutes
|
||||
|
||||
<p/>
|
||||
<button type="submit"><ib:message key="Save"/></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,101 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<c:set var="email" value="${ib:getEmail(param.folder, param.messageID)}"/>
|
||||
|
||||
<ib:setEmailRead folder="${ib:getMailFolder(param.folder)}" messageId="${param.messageID}" read="true"/>
|
||||
|
||||
<c:set var="title" value="${email.subject}" scope="request"/>
|
||||
<jsp:include page="header.jsp"/>
|
||||
|
||||
<div class="emailtext">
|
||||
<table>
|
||||
<tr>
|
||||
<td valign="top"><strong><ib:message key="From:"/></strong></td>
|
||||
<td>
|
||||
<ib:address address="${email.sender}"/>
|
||||
<c:set var="senderDestination" value="${ib:extractEmailDestination(email.sender)}"/>
|
||||
<c:if test="${!empty senderDestination}">
|
||||
<form action="editContact.jsp?new=true&destination=${senderDestination}&name=${ib:extractName(email.sender)}" method="POST">
|
||||
<c:set var="disabled" value="${empty ib:getContact(senderDestination) ? '' : 'disabled=" disabled" title="The Email Destination already exists in the address book."'}"/>
|
||||
<button type="submit"${disabled}><ib:message key="Add to Address Book"/></button>
|
||||
</form>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><strong><ib:message key="To:"/></strong></td>
|
||||
<td>
|
||||
<c:forEach var="recipient" varStatus="status" items="${email.allRecipients}">
|
||||
<ib:address address="${recipient}"/>
|
||||
<c:if test="${!status.last}">,<p/></c:if>
|
||||
</c:forEach>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><strong><ib:message key="Subject:"/></strong></td>
|
||||
<td>${fn:escapeXml(email.subject)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><strong><ib:message key="Message:"/></strong></td>
|
||||
<td><ib:formatPlainText text="${fn:escapeXml(email.text)}"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<table><tr>
|
||||
<td>
|
||||
<form action="newEmail.jsp" method="post">
|
||||
<button type="submit"><ib:message key="Reply"/></button>
|
||||
<input type="hidden" name="sender" value="${ib:getOneLocalRecipient(email)}"/>
|
||||
<input type="hidden" name="recipient0" value="${email.sender}"/>
|
||||
|
||||
<ib:message key="Re:" var="responsePrefix"/>
|
||||
<c:set var="responsePrefix" value="${responsePrefix} "/>
|
||||
<c:if test="${fn:startsWith(email.subject, responsePrefix)}">
|
||||
<c:set var="responsePrefix" value=""/>
|
||||
</c:if>
|
||||
<input type="hidden" name="subject" value="${responsePrefix}${email.subject}"/>
|
||||
|
||||
<input type="hidden" name="quoteMsgFolder" value="${param.folder}"/>
|
||||
<input type="hidden" name="quoteMsgId" value="${param.messageID}"/>
|
||||
</form>
|
||||
</td><td>
|
||||
<form action="deleteEmail.jsp" method="post">
|
||||
<button type="submit"><ib:message key="Delete"/></button>
|
||||
<input type="hidden" name="folder" value="${param.folder}"/>
|
||||
<input type="hidden" name="messageID" value="${email.messageID}"/>
|
||||
</form>
|
||||
</td>
|
||||
</tr></table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<jsp:include page="footer.jsp"/>
|
@ -1,58 +0,0 @@
|
||||
<%--
|
||||
Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
|
||||
The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
|
||||
This file is part of I2P-Bote.
|
||||
I2P-Bote is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
I2P-Bote is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
--%>
|
||||
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
|
||||
|
||||
<jsp:include page="getStatus.jsp"/>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="i2pbote.css" />
|
||||
<meta http-equiv="refresh" content="20" />
|
||||
</head>
|
||||
|
||||
<body style="background-color: transparent; margin: 0px;">
|
||||
|
||||
<div class="statusbox">
|
||||
<c:choose>
|
||||
<c:when test="${connStatus == NOT_STARTED}"><img src="images/redsquare.png"/> <ib:message key="Not Started"/></c:when>
|
||||
<c:when test="${connStatus == DELAY}"><img src="images/yellowsquare.png"/> <ib:message key="Waiting 3 Minutes..."/><br/>
|
||||
<div style="text-align: center">
|
||||
<form action="connect.jsp" target="_top" method="GET">
|
||||
<button type="submit"><ib:message key="Connect Now"/></button>
|
||||
</form>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:when test="${connStatus == CONNECTING}"><img src="images/yellowsquare.png"/> <ib:message key="Connecting..."/></c:when>
|
||||
<c:when test="${connStatus == CONNECTED}"><img src="images/greensquare.png"/> <ib:message key="Connected"/></c:when>
|
||||
<c:when test="${connStatus == ERROR}"><img src="images/redsquare.png"/> <ib:message key="Error"/></c:when>
|
||||
<c:otherwise> <ib:message key="Unknown Status"/></c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
package i2p.bote.ant;
|
||||
|
||||
import i2p.bote.I2PBote;
|
||||
|
||||
public class PrintAppVersion {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(I2PBote.getAppVersion());
|
||||
}
|
||||
}
|
829
build.xml
@ -1,44 +1,200 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project basedir="." default="help" name="I2P-Bote">
|
||||
<property name="i2pbase" value="../i2p"/>
|
||||
<property name="i2plib" value="${i2pbase}/core/java/build"/>
|
||||
<property name="jettylib" value="${i2pbase}/apps/jetty/jettylib"/>
|
||||
<property name="antlib" value="${jettylib}"/>
|
||||
<project basedir="." default="help" name="I2P-Bote" xmlns:if="ant:if" xmlns:unless="ant:unless">
|
||||
<property environment="env"/>
|
||||
<condition property="i2pbase" value="${env.I2P}">
|
||||
<isset property="env.I2P"/>
|
||||
</condition>
|
||||
|
||||
<property name="i2plib" value="${i2pbase}/lib"/>
|
||||
<property name="jstllib" value="${i2pbase}/apps/susidns/src/WEB-INF/lib"/>
|
||||
<property name="lib" value="WebContent/WEB-INF/lib"/>
|
||||
<property name="lib" value="lib"/>
|
||||
<property name="makeplugin" value="../i2p.scripts/plugin/makeplugin.sh"/>
|
||||
|
||||
<property name="junit.filename" value="junit-4.8.1.jar"/>
|
||||
<property name="junit.url" value="http://sourceforge.net/projects/junit/files/junit/4.8.1/junit-4.8.1.jar/download"/>
|
||||
<property name="mockito.filename" value="mockito-core-2.0.31-beta.jar"/>
|
||||
<property name="mockito.url" value="https://bintray.com/artifact/download/szczepiq/maven/org/mockito/mockito-core/2.0.31-beta/mockito-core-2.0.31-beta.jar"/>
|
||||
<!-- Just the main jMock .jar, the .zip contains this and dependencies -->
|
||||
<property name="jmock.filename" value="jmock-2.6.0.jar"/>
|
||||
<property name="jmock.archive" value="jmock-2.6.0-jars.zip"/>
|
||||
<property name="jmockcp" value="${lib}/jmock-2.6.0.jar:${lib}/hamcrest-core-1.3.jar:${lib}/hamcrest-library-1.3.jar:${lib}/jmock-legacy-2.6.0.jar:${lib}/cglib-nodep-2.2.3.jar:${lib}/objenesis-1.0.jar"/>
|
||||
<property name="jmock.url" value="http://jmock.org/downloads/${jmock.archive}"/>
|
||||
|
||||
<!-- Dependencies -->
|
||||
<!-- Local -->
|
||||
<property name="ntruenc.filename" value="ntruenc-1.2.jar"/>
|
||||
<property name="ntruenc.includeinupdate" value="false"/>
|
||||
<property name="scrypt.filename" value="scrypt-1.4.0.jar"/>
|
||||
<property name="scrypt.includeinupdate" value="false"/>
|
||||
<property name="lzma.filename" value="lzma-9.20.jar"/>
|
||||
<property name="lzma.includeinupdate" value="false"/>
|
||||
<property name="gmss.filename" value="flexi-gmss-1.7p1.jar"/>
|
||||
<property name="gmss.includeinupdate" value="false"/>
|
||||
<property name="jcommon.filename" value="jcommon-1.0.23.jar"/>
|
||||
<property name="jcommon.includeinupdate" value="false"/>
|
||||
<property name="jfreechart.filename" value="jfreechart-1.0.19.jar"/>
|
||||
<property name="jfreechart.includeinupdate" value="false"/>
|
||||
<!-- JavaMail -->
|
||||
<property name="mailapi.name" value="JavaMail"/>
|
||||
<property name="mailapi.filename" value="mailapi-1.5.4.jar"/>
|
||||
<property name="mailapi.hash" value="6786437244ec10d05601c52ee418b33e31f7ce5ed2cad8c8893139b28cb18ac3"/>
|
||||
<property name="mailapi.url" value="https://maven.java.net/content/repositories/releases/com/sun/mail/mailapi/1.5.4/mailapi-1.5.4.jar"/>
|
||||
<property name="mailapi.includeinupdate" value="false"/>
|
||||
<!-- BouncyCastle Provider -->
|
||||
<property name="bcprov.name" value="BouncyCastle Provider"/>
|
||||
<property name="bcprov.filename" value="bcprov-jdk15on-152.jar"/>
|
||||
<property name="bcprov.hash" value="0dc4d181e4d347893c2ddbd2e6cd5d7287fc651c03648fa64b2341c7366b1773"/>
|
||||
<property name="bcprov.url" value="http://downloads.bouncycastle.org/java/bcprov-jdk15on-152.jar"/>
|
||||
<property name="bcprov.includeinupdate" value="false"/>
|
||||
<!-- Apache James IMAP server -->
|
||||
<!-- Just one of the James .jars for checking presence of James, the .zip contains this and dependencies -->
|
||||
<property name="james.filename" value="apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
|
||||
<property name="james.archive" value="james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip"/>
|
||||
<!--
|
||||
James snapshots are only kept for a few days. The URL below points to a copy of the 6/27/2015 snapshot.
|
||||
To be replaced with a repository.apache.org URL once beta5 is out.
|
||||
-->
|
||||
<property name="james.url" value="http://download.i2p2.de/mirror/lib/james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip"/>
|
||||
<property name="james.includeinupdate" value="false"/>
|
||||
<!-- SubEtha SMTP -->
|
||||
<property name="subetha.name" value="SubEtha SMTP"/>
|
||||
<property name="subetha.filename" value="subethasmtp-3.1.7.jar"/>
|
||||
<property name="subetha.hash" value="95cf031f1bc1b1a69b08554fbf8970bad994b32db32388d482c6afb482f1db76"/>
|
||||
<property name="subetha.archive" value="subethasmtp-3.1.7.zip"/>
|
||||
<property name="subetha.url" value="http://subethasmtp.googlecode.com/files/subethasmtp-3.1.7.zip"/>
|
||||
<property name="subetha.includeinupdate" value="false"/>
|
||||
|
||||
<!-- the following are only used by win32installer -->
|
||||
<property name="i2p.mtn" value="../i2p.mtn"/>
|
||||
<property name="win32launcherurl" value="http://dist.codehaus.org/izpack/native-launcher/izpack-launcher-1.3.zip"/>
|
||||
<property name="win32jreurl" value="http://javadl.sun.com/webapps/download/AutoDL?BundleId=47363"/>
|
||||
|
||||
<fileset dir="${lib}" id="imaplibs">
|
||||
<include name="apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
|
||||
<include name="apache-james-mailbox-store-0.6-20150508.041003-704.jar"/>
|
||||
<include name="apache-mime4j-core-0.8.0-20150617.024907-738.jar"/>
|
||||
<include name="apache-mime4j-dom-0.8.0-20150617.024927-735.jar"/>
|
||||
<include name="commons-codec-1.7.jar"/>
|
||||
<include name="commons-collections-3.2.1.jar"/>
|
||||
<include name="commons-configuration-1.9.jar"/>
|
||||
<include name="commons-io-2.4.jar"/>
|
||||
<include name="commons-lang-2.6.jar"/>
|
||||
<include name="james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="james-server-util-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="jutf7-1.0.0.jar"/>
|
||||
<include name="log4j-1.2.17.jar"/>
|
||||
<include name="netty-3.3.1.Final.jar"/>
|
||||
<include name="protocols-api-1.6.4-20150617.121129-1080.jar"/>
|
||||
<include name="protocols-imap-1.6.4-20150617.121245-927.jar"/>
|
||||
<include name="protocols-netty-1.6.4-20150617.121137-1044.jar"/>
|
||||
<include name="slf4j-api-1.7.2.jar"/>
|
||||
<include name="slf4j-log4j12-1.7.2.jar"/>
|
||||
</fileset>
|
||||
<path id="cp">
|
||||
<pathelement path="${java.class.path}" />
|
||||
<pathelement location="${i2plib}/i2p.jar" />
|
||||
<pathelement location="${jettylib}/org.mortbay.jetty.jar"/>
|
||||
<pathelement location="${jettylib}/jasper-compiler.jar" />
|
||||
<pathelement location="${jettylib}/jasper-runtime.jar" />
|
||||
<pathelement location="${jettylib}/javax.servlet.jar" />
|
||||
<pathelement location="${jettylib}/commons-logging.jar" />
|
||||
<pathelement location="${jettylib}/commons-el.jar" />
|
||||
<pathelement location="${jstllib}/jstl.jar" />
|
||||
<pathelement location="${jstllib}/standard.jar" />
|
||||
<pathelement location="${lib}/mailapi.jar" />
|
||||
<pathelement location="${i2plib}/mstreaming.jar" />
|
||||
<pathelement location="${i2plib}/streaming.jar" />
|
||||
<pathelement location="${i2plib}/router.jar" />
|
||||
<pathelement location="${i2plib}/org.mortbay.jetty.jar"/>
|
||||
<pathelement location="${i2plib}/jasper-compiler.jar" />
|
||||
<pathelement location="${i2plib}/jasper-runtime.jar" />
|
||||
<pathelement location="${i2plib}/javax.servlet.jar" />
|
||||
<pathelement location="${i2plib}/commons-logging.jar" />
|
||||
<pathelement location="${i2plib}/commons-el.jar" />
|
||||
<pathelement location="${i2plib}/jstl.jar" />
|
||||
<pathelement location="${i2plib}/standard.jar" />
|
||||
<pathelement location="${lib}/${mailapi.filename}" />
|
||||
<pathelement location="${lib}/${bcprov.filename}" />
|
||||
<pathelement location="${lib}/${ntruenc.filename}" />
|
||||
<pathelement location="${lib}/${scrypt.filename}" />
|
||||
<pathelement location="${lib}/${lzma.filename}" />
|
||||
<pathelement location="${lib}/${gmss.filename}" />
|
||||
<pathelement location="${lib}/${subetha.filename}" />
|
||||
<pathelement location="${lib}/${jcommon.filename}" />
|
||||
<pathelement location="${lib}/${jfreechart.filename}" />
|
||||
<pathelement location="src/main/webapp/WEB-INF/classes" />
|
||||
<fileset refid="imaplibs"/>
|
||||
</path>
|
||||
|
||||
<pathconvert property="manifest.classpath" pathsep=" ">
|
||||
<path refid="cp" />
|
||||
<mapper>
|
||||
<flattenmapper />
|
||||
</mapper>
|
||||
</pathconvert>
|
||||
|
||||
|
||||
<target name="help">
|
||||
<echo message="Useful targets:" />
|
||||
<echo message=" war: Makes a .war file" />
|
||||
<echo message=" plugin: Makes a I2P plugin. Only runs on Linux;" />
|
||||
<echo message=" $I2P must point to an I2P installation." />
|
||||
<echo message=" all: war + plugin" />
|
||||
<echo message=" junit: Runs all unit tests" />
|
||||
<echo message=" war: Makes a .war file" />
|
||||
<echo message=" plugin: Makes a I2P plugin. Only runs on Linux." />
|
||||
<echo message=" Requires the i2p.scripts branch to be checked out" />
|
||||
<echo message=" alongside this directory (for makeplugin.sh)." />
|
||||
<echo message=" all: src + war + plugin" />
|
||||
<echo message=" win32installer: Makes a Windows-only installer that installs" />
|
||||
<echo message=" I2P, I2P-Bote, and optionally a JRE. Needs 7z and" />
|
||||
<echo message=" mtn on the path, and a mtn DB containing i2p.i2p." />
|
||||
<echo message=" Requires Ant 1.8.0 or higher." />
|
||||
<echo message=" poupdate: Updates the messages_*.po files from the source code," />
|
||||
<echo message=" adding any untranslated strings. Depends on additional" />
|
||||
<echo message=" software, see bundle-messages.sh." />
|
||||
<echo message=" This task only runs on Linux at the moment." />
|
||||
<echo message=" src: Zips up the source code" />
|
||||
<echo message=" junit: Runs all unit tests" />
|
||||
<echo message=" javadoc: Generates code documentation in the javadoc dir" />
|
||||
<echo message=" clean: Removes all generated files and directories" />
|
||||
<echo message=" distclean: Removes all generated files and directories, and all downloaded libraries" />
|
||||
</target>
|
||||
|
||||
<target name="all" depends="clean, war, plugin" />
|
||||
<target name="all" depends="clean, src, war, plugin" />
|
||||
|
||||
<target name="compile">
|
||||
<target name="checki2pbase">
|
||||
<fail unless="i2pbase" message="The I2P environment variable is not set.${line.separator}It must point to an I2P installation. It is usually a path of the form ${line.separator}/xxx/yyy/i2p."/>
|
||||
</target>
|
||||
|
||||
<macrodef name="checkdep">
|
||||
<attribute name="dep"/>
|
||||
<sequential>
|
||||
<local name="hashValid"/>
|
||||
<checksum file="${lib}/${@{dep}.filename}" algorithm="SHA-256" property="${@{dep}.hash}" verifyProperty="hashValid"/>
|
||||
<fail message="The ${@{dep}.name} library has an invalid hash.">
|
||||
<condition>
|
||||
<isfalse value="${hashValid}"/>
|
||||
</condition>
|
||||
</fail>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<target name="checkdependencies">
|
||||
<available property="mailapiexists" file="${lib}/${mailapi.filename}" type="file"/>
|
||||
<available property="bcprovexists" file="${lib}/${bcprov.filename}" type="file"/>
|
||||
<available property="jamesexists" file="${lib}/${james.filename}" type="file"/>
|
||||
<available property="subethaexists" file="${lib}/${subetha.filename}" type="file"/>
|
||||
|
||||
<ant target="downloadmailapi"/>
|
||||
<ant target="downloadbcprov"/>
|
||||
<ant target="downloadjames"/>
|
||||
<ant target="downloadsubetha"/>
|
||||
|
||||
<checkdep dep="mailapi"/>
|
||||
<checkdep dep="bcprov"/>
|
||||
<checkdep dep="subetha"/>
|
||||
</target>
|
||||
|
||||
<!-- compiles everything under src/main/java, but not src/test/ or src/build/ -->
|
||||
<target name="compile" depends="checki2pbase, checkdependencies">
|
||||
<mkdir dir="./ant_build" />
|
||||
<mkdir dir="./ant_build/classes" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
srcdir="./src/main/java"
|
||||
debug="true"
|
||||
deprecation="on"
|
||||
source="1.6" target="1.6"
|
||||
includeAntRuntime="false"
|
||||
destdir="./ant_build/classes"
|
||||
classpathref="cp"
|
||||
failonerror="true" />
|
||||
@ -60,37 +216,44 @@
|
||||
<arg value="-webinc" />
|
||||
<arg value="ant_build/web-fragment.xml" />
|
||||
<arg value="-webapp" />
|
||||
<arg value="WebContent" />
|
||||
<arg value="src/main/webapp" />
|
||||
</java>
|
||||
|
||||
<javac
|
||||
debug="true"
|
||||
deprecation="on"
|
||||
source="1.6" target="1.6"
|
||||
includeAntRuntime="false"
|
||||
destdir="ant_build/classes"
|
||||
srcdir="./ant_build/jspjava"
|
||||
includes="**/*.java"
|
||||
classpathref="jspcp"
|
||||
failonerror="true" />
|
||||
<copy file="WebContent/WEB-INF/web.xml" tofile="ant_build/web.xml" />
|
||||
<copy file="src/main/webapp/WEB-INF/web.xml" tofile="ant_build/web.xml" />
|
||||
<loadfile property="jspc.web.fragment" srcfile="ant_build/web-fragment.xml" />
|
||||
<replace file="ant_build/web.xml">
|
||||
<replacefilter token="<!-- precompiled servlets -->" value="${jspc.web.fragment}" />
|
||||
</replace>
|
||||
</target>
|
||||
|
||||
<target name="war" depends="compile,precompilejsp,bundle">
|
||||
<target name="war" depends="jar">
|
||||
<mkdir dir="ant_build" />
|
||||
<war destfile="i2pbote.war" webxml="ant_build/web.xml">
|
||||
<classes dir="ant_build/classes" includes="**/*.class" />
|
||||
<classes dir="src" includes="i2p/bote/network/kademlia/built-in-peers.txt" />
|
||||
<fileset dir="WebContent" includes="index.html"/>
|
||||
<fileset dir="WebContent" includes="*.css"/>
|
||||
<fileset dir="WebContent/" includes="*.xml"/>
|
||||
<webinf dir="WebContent/WEB-INF/tlds" includes="*.tld"/>
|
||||
<lib file="${jstllib}/jstl.jar"/>
|
||||
<lib file="${jstllib}/standard.jar"/>
|
||||
<lib file="${lib}/mailapi.jar"/>
|
||||
<zipfileset dir="WebContent/images" prefix="images"/>
|
||||
<classes dir="ant_build/classes" includes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/**" />
|
||||
<fileset dir="src/main/webapp" includes="*.html"/>
|
||||
<fileset dir="src/main/webapp/" includes="*.xml"/>
|
||||
<webinf dir="src/main/webapp/WEB-INF/tlds" includes="*.tld"/>
|
||||
<lib file="${lib}/i2pbote.jar"/>
|
||||
<lib file="${lib}/${mailapi.filename}"/>
|
||||
<lib file="${lib}/${bcprov.filename}"/>
|
||||
<lib file="${lib}/${ntruenc.filename}"/>
|
||||
<lib file="${lib}/${scrypt.filename}"/>
|
||||
<lib file="${lib}/${lzma.filename"/>
|
||||
<lib file="${lib}/${gmss.filename}"/>
|
||||
<lib file="${lib}/${jcommon.filename}" />
|
||||
<lib file="${lib}/${jfreechart.filename}" />
|
||||
<zipfileset dir="src/main/webapp/html" prefix="html"/>
|
||||
<zipfileset dir="src/main/webapp/themes" prefix="themes"/>
|
||||
</war>
|
||||
|
||||
<echo message="SHA256 sum:"/>
|
||||
@ -99,9 +262,43 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile,precompilejsp,bundle">
|
||||
<mkdir dir="ant_build" />
|
||||
<jar destfile="${lib}/i2pbote.jar">
|
||||
<fileset dir="ant_build/classes" excludes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/** codec/** **/*Test.class"/>
|
||||
<fileset dir="src/main/java" includes="i2p/bote/network/built-in-peers.txt"/>
|
||||
<fileset dir="src/main/java" includes="i2p/bote/crypto/wordlist/"/>
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="${manifest.classpath}" />
|
||||
</manifest>
|
||||
<metainf file="src/main/webapp/META-INF/mime.types"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<macrodef name="packdep">
|
||||
<attribute name="dep"/>
|
||||
<element name="exec-args" optional="yes" implicit="yes"/>
|
||||
<sequential>
|
||||
<exec executable="pack200" failonerror="true">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
<exec-args/>
|
||||
<arg value="plugin/plugin.tmp/lib/${@{dep}.filename}.pack"/>
|
||||
<arg value="${lib}/${@{dep}.filename}"/>
|
||||
</exec>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="removepack">
|
||||
<attribute name="dep"/>
|
||||
<sequential>
|
||||
<delete file="plugin/plugin.tmp/lib/${@{dep}.filename}"/>
|
||||
<delete file="plugin/plugin.tmp/lib/${@{dep}.filename}.pack"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<!--
|
||||
- Make two plugins, one for initial installs and one for updates.
|
||||
- Only the initial install includes mailapi.jar.
|
||||
- Neither includes jstl.jar or standard.jar, as any i2p version that has
|
||||
- plugin support has these two jars pulled out of susidns.war and put in
|
||||
- $I2P/lib. We set the classpath in webapps.config to find them.
|
||||
@ -111,9 +308,9 @@
|
||||
<mkdir dir="plugin/plugin.tmp/console/webapps" />
|
||||
<copy file="plugin/webapps.config" todir="plugin/plugin.tmp/console/" />
|
||||
|
||||
<!-- run i2pbote-plugin.war through pack200 -->
|
||||
<!-- run all .jars and i2pbote-plugin.war through pack200 -->
|
||||
<move file="i2pbote-plugin.war" tofile="plugin/plugin.tmp/console/webapps/i2pbote.jar" />
|
||||
<exec executable="pack200" failifexecutionfails="true">
|
||||
<exec executable="pack200" failonerror="true">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
@ -121,105 +318,368 @@
|
||||
<arg value="plugin/plugin.tmp/console/webapps/i2pbote.jar"/>
|
||||
</exec>
|
||||
<delete file="plugin/plugin.tmp/console/webapps/i2pbote.jar" />
|
||||
<exec executable="pack200" failonerror="true">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
<arg value="plugin/plugin.tmp/lib/i2pbote.jar.pack"/>
|
||||
<arg value="${lib}/i2pbote.jar"/>
|
||||
</exec>
|
||||
|
||||
<delete file="plugin/plugin.tmp/lib/mailapi.jar" />
|
||||
<!-- pack local dependencies in updater -->
|
||||
<includedep updater="true" dep="ntruenc"/>
|
||||
<includedep updater="true" dep="scrypt"/>
|
||||
<includedep updater="true" dep="lzma"/>
|
||||
<includedep updater="true" dep="gmss"/>
|
||||
<includedep updater="true" dep="jcommon"/>
|
||||
<includedep updater="true" dep="jfreechart"/>
|
||||
<!-- pack remote dependencies in updater -->
|
||||
<includedep updater="true" dep="mailapi"/>
|
||||
<includedep updater="true" dep="bcprov"/>
|
||||
<includedep updater="true" dep="james"/>
|
||||
<includedep updater="true" dep="subetha"/>
|
||||
|
||||
<copy file="src/main/scripts/encrypt.sh" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="src/main/scripts/decrypt.sh" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="src/main/scripts/fileinfo.sh" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="src/main/scripts/encrypt.bat" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="src/main/scripts/decrypt.bat" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="src/main/scripts/fileinfo.bat" todir="plugin/plugin.tmp/lib"/>
|
||||
|
||||
<!-- get build number -->
|
||||
<buildnumber file="plugin/build.number" />
|
||||
|
||||
<!-- make the update xpi2p -->
|
||||
<copy file="plugin/plugin.config" todir="plugin/plugin.tmp" overwrite="true" />
|
||||
<exec executable="echo" osfamily="unix" failifexecutionfails="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<arg value="version=${version}-b${build.number}" />
|
||||
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<arg value="version=${version}" />
|
||||
</exec>
|
||||
<exec executable="echo" osfamily="unix" failifexecutionfails="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<arg value="update-only=true" />
|
||||
</exec>
|
||||
<exec executable="${makeplugin}" failifexecutionfails="true" >
|
||||
<input message="Enter key password for plugin-su3-keystore.ks:" addproperty="release.password.su3" />
|
||||
<fail message="You must enter a password." >
|
||||
<condition>
|
||||
<equals arg1="${release.password.su3}" arg2=""/>
|
||||
</condition>
|
||||
</fail>
|
||||
<exec executable="${makeplugin}" inputstring="${release.password.su3}" failonerror="true" >
|
||||
<arg value="plugin/plugin.tmp" />
|
||||
</exec>
|
||||
<move file="i2pbote.xpi2p" tofile="i2pbote-update.xpi2p" />
|
||||
<move file="i2pbote.su3" tofile="i2pbote-update.su3" />
|
||||
|
||||
<!-- pack local dependencies in installer -->
|
||||
<includedep dep="ntruenc"/>
|
||||
<includedep dep="scrypt"/>
|
||||
<includedep dep="lzma"/>
|
||||
<includedep dep="gmss"/>
|
||||
<includedep dep="jcommon"/>
|
||||
<includedep dep="jfreechart"/>
|
||||
<!-- pack remote dependencies in installer -->
|
||||
<includedep dep="mailapi"/>
|
||||
<includedep dep="bcprov"/>
|
||||
<includedep dep="james"/>
|
||||
<includedep dep="subetha"/>
|
||||
|
||||
<!-- make the install xpi2p -->
|
||||
<exec executable="pack200" failifexecutionfails="true">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
<arg value="plugin/plugin.tmp/lib/mailapi.jar.pack"/>
|
||||
<arg value="${lib}/mailapi.jar"/>
|
||||
</exec>
|
||||
<copy file="plugin/plugin.config" todir="plugin/plugin.tmp" overwrite="true" />
|
||||
<exec executable="echo" osfamily="unix" failifexecutionfails="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<arg value="version=${version}-b${build.number}" />
|
||||
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
|
||||
<arg value="version=${version}" />
|
||||
</exec>
|
||||
<exec executable="${makeplugin}" >
|
||||
<exec executable="${makeplugin}" inputstring="${release.password.su3}" failonerror="true" >
|
||||
<arg value="plugin/plugin.tmp" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- same as war but without the library jars -->
|
||||
<target name="pluginwar" depends="compile,precompilejsp,bundle">
|
||||
<target name="pluginwar" depends="compile,jar,precompilejsp,bundle">
|
||||
<mkdir dir="ant_build" />
|
||||
<war destfile="i2pbote-plugin.war" webxml="ant_build/web.xml">
|
||||
<classes dir="ant_build/classes" includes="**/*.class" />
|
||||
<classes dir="src" includes="i2p/bote/network/kademlia/built-in-peers.txt" />
|
||||
<fileset dir="WebContent" includes="index.html"/>
|
||||
<fileset dir="WebContent" includes="*.css"/>
|
||||
<fileset dir="WebContent/" includes="*.xml"/>
|
||||
<webinf dir="WebContent/WEB-INF/tlds" includes="*.tld"/>
|
||||
<zipfileset dir="WebContent/images" prefix="images"/>
|
||||
<classes dir="ant_build/classes" includes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/**" />
|
||||
<fileset dir="src/main/webapp" includes="*.html"/>
|
||||
<fileset dir="src/main/webapp/" includes="*.xml"/>
|
||||
<webinf dir="src/main/webapp/WEB-INF/tlds" includes="*.tld"/>
|
||||
<zipfileset dir="src/main/webapp/html" prefix="html"/>
|
||||
<zipfileset dir="src/main/webapp/themes" prefix="themes"/>
|
||||
</war>
|
||||
</target>
|
||||
|
||||
<target name="bundle">
|
||||
|
||||
<macrodef name="includedep">
|
||||
<attribute name="updater" default="false"/>
|
||||
<attribute name="dep"/>
|
||||
<sequential>
|
||||
<local name="packDep"/>
|
||||
<local name="removePack"/>
|
||||
<condition property="packDep" else="false">
|
||||
<or>
|
||||
<and>
|
||||
<istrue value="@{updater}"/>
|
||||
<istrue value="${@{dep}.includeinupdate}"/>
|
||||
</and>
|
||||
<and>
|
||||
<isfalse value="@{updater}"/>
|
||||
<isfalse value="${@{dep}.includeinupdate}"/>
|
||||
</and>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="removePack" else="false">
|
||||
<and>
|
||||
<istrue value="@{updater}"/>
|
||||
<isfalse value="${@{dep}.includeinupdate}"/>
|
||||
</and>
|
||||
</condition>
|
||||
|
||||
<ant target="packdep.@{dep}" if:true="${packDep}"/>
|
||||
<ant target="removepack.@{dep}" if:true="${removePack}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<target name="packdep.ntruenc">
|
||||
<packdep dep="ntruenc"/>
|
||||
</target>
|
||||
<target name="removepack.ntruenc">
|
||||
<removepack dep="ntruenc"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.scrypt">
|
||||
<packdep dep="scrypt"/>
|
||||
</target>
|
||||
<target name="removepack.scrypt">
|
||||
<removepack dep="scrypt"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.lzma">
|
||||
<packdep dep="lzma"/>
|
||||
</target>
|
||||
<target name="removepack.lzma">
|
||||
<removepack dep="lzma"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.gmss">
|
||||
<packdep dep="gmss"/>
|
||||
</target>
|
||||
<target name="removepack.gmss">
|
||||
<removepack dep="gmss"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.jcommon">
|
||||
<packdep dep="jcommon"/>
|
||||
</target>
|
||||
<target name="removepack.jcommon">
|
||||
<removepack dep="jcommon"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.jfreechart">
|
||||
<packdep dep="jfreechart"/>
|
||||
</target>
|
||||
<target name="removepack.jfreechart">
|
||||
<removepack dep="jfreechart"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.mailapi">
|
||||
<packdep dep="mailapi"/>
|
||||
</target>
|
||||
<target name="removepack.mailapi">
|
||||
<removepack dep="mailapi"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.bcprov">
|
||||
<packdep dep="bcprov">
|
||||
<arg value="--segment-limit=-1"/>
|
||||
</packdep>
|
||||
</target>
|
||||
<target name="removepack.bcprov">
|
||||
<removepack dep="bcprov"/>
|
||||
</target>
|
||||
|
||||
<target name="packdep.james">
|
||||
<apply executable="pack200" failonerror="true" parallel="false" dest="plugin/plugin.tmp/lib/">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
<targetfile/>
|
||||
<srcfile/>
|
||||
<fileset refid="imaplibs"/>
|
||||
<mapper type="glob" from="*.jar" to="*.jar.pack"/>
|
||||
</apply>
|
||||
</target>
|
||||
<target name="removepack.james">
|
||||
<apply executable="rm" dest="plugin/plugin.tmp/lib/" addsourcefile="false">
|
||||
<targetfile/>
|
||||
<fileset refid="imaplibs"/>
|
||||
<flattenmapper/>
|
||||
</apply>
|
||||
<apply executable="rm" dest="plugin/plugin.tmp/lib/" addsourcefile="false">
|
||||
<targetfile suffix=".pack"/>
|
||||
<fileset refid="imaplibs"/>
|
||||
<flattenmapper/>
|
||||
</apply>
|
||||
</target>
|
||||
|
||||
<target name="packdep.subetha">
|
||||
<packdep dep="subetha"/>
|
||||
</target>
|
||||
<target name="removepack.subetha">
|
||||
<removepack dep="subetha"/>
|
||||
</target>
|
||||
|
||||
<target name="bundle" depends="compile">
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fai
|
||||
l property to true -->
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="false" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="poupdate">
|
||||
<!-- depends on compileantclasses for SearchAndInsert.class -->
|
||||
<target name="win32installer" depends="pluginwar, compileantclasses">
|
||||
<property name="installerdir" value="ant_build/win32installer"/>
|
||||
<property name="installerresources" value="${installerdir}/resources"/>
|
||||
<property name="i2pinstallerdir" value="${installerdir}/i2p.i2p/installer"/>
|
||||
<property name="i2pinstallerplugindir" value="${installerdir}/i2p.i2p/plugins/i2pbote"/>
|
||||
<mkdir dir="${installerdir}"/>
|
||||
|
||||
<!-- get 7z_extra.7z and extract 7zS.sfx -->
|
||||
<get src="http://sourceforge.net/projects/sevenzip/files/7-Zip/9.19/7z919_extra.7z/download" dest="${installerdir}/7z_extra.7z" skipexisting="true"/>
|
||||
<exec executable="7z" dir="${installerdir}">
|
||||
<arg value="e"/>
|
||||
<arg value="-y"/>
|
||||
<arg value="7z_extra.7z"/>
|
||||
<arg value="7zS.sfx"/>
|
||||
</exec>
|
||||
|
||||
<!-- check out i2p.i2p from mtn, add i2pbote, and build install.jar -->
|
||||
<delete dir="${installerdir}/i2p.i2p" />
|
||||
<exec executable="mtn" dir="${installerdir}" failonerror="true">
|
||||
<arg value="--db" />
|
||||
<arg value="../../${i2p.mtn}" />
|
||||
<arg value="--branch" />
|
||||
<arg value="i2p.i2p" />
|
||||
<arg value="co" />
|
||||
</exec>
|
||||
<!-- add I2P-Bote to install.xml -->
|
||||
<java classname="i2p.bote.ant.SearchAndInsert" classpathref="cp" classpath="./ant_build/classes" failonerror="true">
|
||||
<arg value="-before"/>
|
||||
<arg value="${i2pinstallerdir}/install.xml"/>
|
||||
<arg value="${i2pinstallerdir}/install.xml.new"/>
|
||||
<arg value="</packs>"/>
|
||||
<arg value="win32installer/i2pbote_pack.txt"/>
|
||||
</java>
|
||||
<move file="${i2pinstallerdir}/install.xml.new" tofile="${i2pinstallerdir}/install.xml"/>
|
||||
<!-- make the plugins dir -->
|
||||
<mkdir dir="${i2pinstallerplugindir}/console/webapps"/>
|
||||
<mkdir dir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="plugin/plugin.config" todir="${i2pinstallerplugindir}"/>
|
||||
<copy file="i2pbote-plugin.war" tofile="${i2pinstallerplugindir}/console/webapps/i2pbote.war"/>
|
||||
<copy file="plugin/webapps.config" todir="${i2pinstallerplugindir}/console"/>
|
||||
<copy file="${lib}/i2pbote.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/${mailapi.filename}" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/${bcprov.filename}" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/ntruenc-1.2.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/scrypt-1.4.0.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/lzma-9.20.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/flexi-gmss-1.7p1.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/jcommon-1.0.23.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<copy file="${lib}/jfreechart-1.0.19.jar" todir="${i2pinstallerplugindir}/lib"/>
|
||||
<!-- build the I2P + I2P-Bote install.jar -->
|
||||
<ant antfile="${installerdir}/i2p.i2p/build.xml" target="installer" inheritAll="false"/>
|
||||
<copy file="${installerdir}/i2p.i2p/install.jar" todir="${installerresources}"/>
|
||||
|
||||
<!-- download Windows JRE -->
|
||||
<get src="${win32jreurl}" verbose="true" dest="${installerresources}/jre.exe" skipexisting="true"/>
|
||||
<copy file="win32installer/jreinstall.bat" todir="${installerresources}"/>
|
||||
<copy file="win32installer/launcher.ini" todir="${installerresources}"/>
|
||||
<copy file="win32installer/config.txt" todir="${installerdir}"/>
|
||||
|
||||
<!-- download the launcher .zip and unzip dist/* to resources/ -->
|
||||
<get src="${win32launcherurl}" verbose="true" dest="${installerdir}/izpack-launcher.zip" skipexisting="true"/>
|
||||
<unzip src="${installerdir}/izpack-launcher.zip" dest="${installerresources}">
|
||||
<patternset>
|
||||
<include name="*/dist/*"/>
|
||||
</patternset>
|
||||
<flattenmapper/>
|
||||
</unzip>
|
||||
|
||||
<exec executable="7z" dir="${installerresources}" failonerror="true">
|
||||
<arg value="a"/>
|
||||
<arg value="../files.7z"/>
|
||||
<arg value="*"/>
|
||||
</exec>
|
||||
|
||||
<concat destfile="i2pinstall.exe" binary="true">
|
||||
<fileset dir="${installerdir}" includes="7zS.sfx, config.txt, files.7z"/>
|
||||
</concat>
|
||||
</target>
|
||||
|
||||
<!-- depends on compileantclasses for JspStrings.class -->
|
||||
<target name="poupdate" depends="compileantclasses">
|
||||
<!-- Update the messages_*.po files. -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<exec executable="sh" osfamily="unix" failonerror="true" >
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<exec executable="sh" osfamily="mac" failonerror="true" >
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="true" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
<exec executable="sh" osfamily="windows" failifexecutionfails="true" >
|
||||
<arg value="src/build/scripts/bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- compiles the Java code in the ant directory -->
|
||||
<target name="compileantclasses" depends="compile">
|
||||
<javac
|
||||
srcdir="./src/build/java"
|
||||
debug="true"
|
||||
deprecation="on"
|
||||
source="1.6" target="1.6"
|
||||
includeAntRuntime="false"
|
||||
destdir="./ant_build/classes"
|
||||
classpathref="cp"
|
||||
classpath="./ant_build/classes"
|
||||
failonerror="true" />
|
||||
</target>
|
||||
|
||||
<target name="junit" depends="compile">
|
||||
<available property="junitexists" file="${lib}/${junit.filename}" type="file"/>
|
||||
<ant target="downloadjunit"/>
|
||||
<available property="mockitoexists" file="${lib}/${mockito.filename}" type="file"/>
|
||||
<ant target="downloadmockito"/>
|
||||
<available property="jmockexists" file="${lib}/${jmock.filename}" type="file"/>
|
||||
<ant target="downloadjmock"/>
|
||||
|
||||
<path id="junitcp">
|
||||
<pathelement location="${lib}/junit.jar"/>
|
||||
<pathelement location="${lib}/${junit.filename}"/>
|
||||
<pathelement location="${lib}/${mockito.filename}"/>
|
||||
<pathelement path="${jmockcp}"/>
|
||||
<pathelement location="./ant_build/classes"/>
|
||||
<path refid="cp"/>
|
||||
</path>
|
||||
|
||||
<javac
|
||||
srcdir="./test"
|
||||
srcdir="./src/test/java"
|
||||
debug="true"
|
||||
deprecation="on"
|
||||
source="1.6" target="1.6"
|
||||
includeAntRuntime="false"
|
||||
destdir="./ant_build/classes"
|
||||
classpathref="junitcp"
|
||||
failonerror="true" />
|
||||
<copy file="src/test/java/i2p/bote/packet/dht/Struwwelpeter.jpg" tofile="ant_build/classes/i2p/bote/packet/dht/Struwwelpeter.jpg"/>
|
||||
<copy file="src/main/java/i2p/bote/crypto/wordlist/words_de.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_de.txt"/>
|
||||
<copy file="src/main/java/i2p/bote/crypto/wordlist/words_en.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_en.txt"/>
|
||||
|
||||
<junit printsummary="off">
|
||||
<echo message="Running JUnit tests..."/>
|
||||
<junit printsummary="off" failureproperty="failed">
|
||||
<classpath>
|
||||
<path refid="junitcp"/>
|
||||
</classpath>
|
||||
@ -228,14 +688,138 @@ l property to true -->
|
||||
<formatter type="plain"/>
|
||||
</batchtest>
|
||||
</junit>
|
||||
<condition property="result"
|
||||
value="At least one unit test failed."
|
||||
else="All unit tests were successful.">
|
||||
<isset property="failed"/>
|
||||
</condition>
|
||||
<echo message="${result}"/>
|
||||
<echo message="For details, see ant_build/TEST*"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadjunit" unless="junitexists">
|
||||
<input message="JUnit not found, download now?" validargs="y,n" addproperty="userinput.junit"/>
|
||||
<fail message="OK, aborting build.">
|
||||
<condition>
|
||||
<equals arg1="${userinput.junit}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${junit.url}" verbose="true" dest="${lib}/${junit.filename}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadmockito" unless="mockitoexists">
|
||||
<input message="Mockito not found, download now?" validargs="y,n" addproperty="userinput.mockito"/>
|
||||
<fail message="OK, aborting build." >
|
||||
<condition>
|
||||
<equals arg1="${userinput.mockito}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${mockito.url}" verbose="true" dest="${lib}/${mockito.filename}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadjmock" unless="jmockexists">
|
||||
<input message="jMock not found, download now?" validargs="y,n" addproperty="userinput.jmock"/>
|
||||
<fail message="OK, aborting build." >
|
||||
<condition>
|
||||
<equals arg1="${userinput.jmock}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${jmock.url}" verbose="true" dest="${lib}/${jmock.archive}"/>
|
||||
<unzip src="${lib}/${jmock.archive}" dest="${lib}">
|
||||
<patternset includes="**/*.jar"/>
|
||||
<mapper>
|
||||
<flattenmapper/>
|
||||
</mapper>
|
||||
</unzip>
|
||||
<delete file="${lib}/${jmock.archive}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadmailapi" unless="mailapiexists">
|
||||
<input message="JavaMail not found, download now?" validargs="y,n" addproperty="userinput.mailapi"/>
|
||||
<fail message="OK, aborting build.">
|
||||
<condition>
|
||||
<equals arg1="${userinput.mailapi}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${mailapi.url}" verbose="true" dest="${lib}/${mailapi.filename}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadbcprov" unless="bcprovexists">
|
||||
<input message="BouncyCastle Provider not found, download now?" validargs="y,n" addproperty="userinput.bcprov"/>
|
||||
<fail message="OK, aborting build.">
|
||||
<condition>
|
||||
<equals arg1="${userinput.bcprov}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${bcprov.url}" verbose="true" dest="${lib}/${bcprov.filename}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadjames" unless="jamesexists">
|
||||
<input message="Apache James not found, download now?" validargs="y,n" addproperty="userinput.junit"/>
|
||||
<fail message="OK, aborting build.">
|
||||
<condition>
|
||||
<equals arg1="${userinput.junit}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${james.url}" verbose="true" dest="${lib}/${james.archive}"/>
|
||||
<unzip src="${lib}/${james.archive}" dest="${lib}">
|
||||
<patternset>
|
||||
<include name="**/apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
|
||||
<include name="**/apache-james-mailbox-store-0.6-20150508.041003-704.jar"/>
|
||||
<include name="**/apache-mime4j-core-0.8.0-20150617.024907-738.jar"/>
|
||||
<include name="**/apache-mime4j-dom-0.8.0-20150617.024927-735.jar"/>
|
||||
<include name="**/commons-codec-1.7.jar"/>
|
||||
<include name="**/commons-collections-3.2.1.jar"/>
|
||||
<include name="**/commons-configuration-1.9.jar"/>
|
||||
<include name="**/commons-io-2.4.jar"/>
|
||||
<include name="**/commons-lang-2.6.jar"/>
|
||||
<include name="**/james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="**/james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="**/james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="**/james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="**/james-server-util-3.0.0-beta5-SNAPSHOT.jar"/>
|
||||
<include name="**/jutf7-1.0.0.jar"/>
|
||||
<include name="**/log4j-1.2.17.jar"/>
|
||||
<include name="**/netty-3.3.1.Final.jar"/>
|
||||
<include name="**/protocols-api-1.6.4-20150617.121129-1080.jar"/>
|
||||
<include name="**/protocols-imap-1.6.4-20150617.121245-927.jar"/>
|
||||
<include name="**/protocols-netty-1.6.4-20150617.121137-1044.jar"/>
|
||||
<include name="**/slf4j-api-1.7.2.jar"/>
|
||||
<include name="**/slf4j-log4j12-1.7.2.jar"/>
|
||||
</patternset>
|
||||
<mapper>
|
||||
<flattenmapper/>
|
||||
</mapper>
|
||||
</unzip>
|
||||
<delete file="${lib}/${james.archive}"/>
|
||||
</target>
|
||||
|
||||
<target name="downloadsubetha" unless="subethaexists">
|
||||
<input message="SubEtha SMTP not found, download now?" validargs="y,n" addproperty="userinput.junit"/>
|
||||
<fail message="OK, aborting build.">
|
||||
<condition>
|
||||
<equals arg1="${userinput.junit}" arg2="n"/>
|
||||
</condition>
|
||||
</fail>
|
||||
<get src="${subetha.url}" verbose="true" dest="${lib}/${subetha.archive}"/>
|
||||
<unzip src="${lib}/${subetha.archive}" dest="${lib}">
|
||||
<patternset includes="**/${subetha.filename}"/>
|
||||
<mapper>
|
||||
<flattenmapper/>
|
||||
</mapper>
|
||||
</unzip>
|
||||
<delete file="${lib}/${subetha.archive}"/>
|
||||
</target>
|
||||
|
||||
<!-- Write the app version into ${version} -->
|
||||
<!-- Depends on compile b/c it gets the app version from I2PBote.class -->
|
||||
<target name="getversion" depends="compile">
|
||||
<javac
|
||||
srcdir="./ant"
|
||||
srcdir="./src/build/java"
|
||||
debug="true"
|
||||
deprecation="on"
|
||||
source="1.6" target="1.6"
|
||||
includeAntRuntime="false"
|
||||
destdir="./ant_build/classes"
|
||||
classpathref="cp"
|
||||
classpath="./ant_build/classes"
|
||||
@ -250,16 +834,17 @@ l property to true -->
|
||||
<echo message="I2P-Bote version is ${version}"/>
|
||||
</target>
|
||||
|
||||
<!-- depends on compile b/c it gets the app version from I2PBote.class -->
|
||||
<target name="src" depends="getversion">
|
||||
<property name="subdir" value="i2pbote-${version}-src"/>
|
||||
<zip destfile="src.zip">
|
||||
<zipfileset dir="src" prefix="${subdir}/src"/>
|
||||
<zipfileset dir="WebContent" prefix="${subdir}/WebContent"/>
|
||||
<zipfileset dir="test" prefix="${subdir}/test"/>
|
||||
<zipfileset dir="ant" prefix="${subdir}/ant"/>
|
||||
<zipfileset dir="src" prefix="${subdir}/src" followsymlinks="false"/>
|
||||
<zipfileset dir="doc" prefix="${subdir}/doc"/>
|
||||
<zipfileset dir="plugin" prefix="${subdir}/plugin">
|
||||
<exclude name="plugin.tmp/**"/>
|
||||
</zipfileset>
|
||||
<zipfileset file="build.xml" prefix="${subdir}"/>
|
||||
<zipfileset file="locale/messages_de.po" prefix="${subdir}/locale"/>
|
||||
<zipfileset file="src/build/scripts/bundle-messages.sh" prefix="${subdir}"/>
|
||||
<zipfileset file="history.txt" prefix="${subdir}"/>
|
||||
<zipfileset file="license.txt" prefix="${subdir}"/>
|
||||
</zip>
|
||||
@ -270,13 +855,81 @@ l property to true -->
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="javadoc" depends="getversion">
|
||||
<!--
|
||||
Instead of eepgetting the package list, it would be easier to just let Ant
|
||||
do it through the eeproxy:
|
||||
|
||||
<javadoc ...>
|
||||
<link href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/"/>
|
||||
|
||||
But Ant falls back to no proxy if a proxied download fails, so eepget is preferable.
|
||||
-->
|
||||
<mkdir dir="ant_build" />
|
||||
<property name="pkglistdir" value="ant_build/package_lists"/>
|
||||
<mkdir dir="${pkglistdir}" />
|
||||
<echo message="Downloading package lists"/>
|
||||
|
||||
<mkdir dir="${pkglistdir}/jdk"/>
|
||||
<java classname="net.i2p.util.EepGet" classpath="${i2plib}/i2p.jar">
|
||||
<arg value="-o"/>
|
||||
<arg value="${pkglistdir}/jdk/package-list"/>
|
||||
<arg value="http://docs.oracle.com/javase/6/docs/api/package-list"/>
|
||||
</java>
|
||||
<mkdir dir="${pkglistdir}/servlet"/>
|
||||
<java classname="net.i2p.util.EepGet" classpath="${i2plib}/i2p.jar">
|
||||
<arg value="-o"/>
|
||||
<arg value="${pkglistdir}/servlet/package-list"/>
|
||||
<arg value="http://docs.oracle.com/javaee/1.4/api/package-list"/>
|
||||
</java>
|
||||
<mkdir dir="${pkglistdir}/javamail"/>
|
||||
<java classname="net.i2p.util.EepGet" classpath="${i2plib}/i2p.jar">
|
||||
<arg value="-o"/>
|
||||
<arg value="${pkglistdir}/javamail/package-list"/>
|
||||
<arg value="http://java.sun.com/products/javamail/javadocs/package-list"/>
|
||||
</java>
|
||||
<mkdir dir="${pkglistdir}/bouncycastle"/>
|
||||
<java classname="net.i2p.util.EepGet" classpath="${i2plib}/i2p.jar">
|
||||
<arg value="-o"/>
|
||||
<arg value="${pkglistdir}/bouncycastle/package-list"/>
|
||||
<arg value="http://bouncycastle.org/docs/docs1.6/package-list"/>
|
||||
</java>
|
||||
|
||||
<javadoc
|
||||
sourcepath="src"
|
||||
destdir="javadoc"
|
||||
classpathref="cp"
|
||||
windowtitle="I2P-Bote"
|
||||
doctitle="I2P-Bote ${version} Javadoc"
|
||||
use="true"
|
||||
linksource="yes">
|
||||
<arg value="-J-Dhttp.proxyHost=localhost"/>
|
||||
<arg value="-J-Dhttp.proxyPort=4444"/>
|
||||
<link href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/" offline="true" packagelistloc="${pkglistdir}/jdk"/>
|
||||
<link href="http://download.oracle.com/docs/cd/E17477_01/javaee/1.4/api/" offline="true" packagelistloc="${pkglistdir}/servlet"/>
|
||||
<link href="http://java.sun.com/products/javamail/javadocs/" offline="true" packagelistloc="${pkglistdir}/javamail"/>
|
||||
<link href="http://bouncycastle.org/docs/docs1.6/" offline="true" packagelistloc="${pkglistdir}/bouncycastle"/>
|
||||
<link href="http://i2p-javadocs.i2p/"/>
|
||||
</javadoc>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="ant_build" />
|
||||
<delete file="${lib}/i2pbote.jar" />
|
||||
<delete file="i2pbote.war" />
|
||||
<delete file="i2pbote-plugin.war" />
|
||||
<delete dir="plugin/plugin.tmp" />
|
||||
<delete file="i2pbote.xpi2p" />
|
||||
<delete file="i2pbote-update.xpi2p" />
|
||||
<delete file="src.zip" />
|
||||
<delete file="i2pinstall.exe" />
|
||||
<delete dir="javadoc" />
|
||||
</target>
|
||||
|
||||
<target name="distclean" depends="clean">
|
||||
<delete>
|
||||
<fileset refid="imaplibs"/>
|
||||
</delete>
|
||||
<delete file="${lib}/${subetha.filename}" />
|
||||
</target>
|
||||
</project>
|
||||
|
BIN
doc/manual.odt
Normal file
BIN
doc/manual_fr.odt
Normal file
999
doc/techdoc.txt
@ -1,18 +0,0 @@
|
||||
I2P-Bote
|
||||
--------
|
||||
|
||||
This file explains how to use I2P-Bote. For technical documentation, see techdoc.txt.
|
||||
|
||||
1. To install the app, [TODO]
|
||||
|
||||
2. Set up an email address [TODO]
|
||||
|
||||
3. Send a test email to yourself [TODO]
|
||||
|
||||
4. Checking for email
|
||||
|
||||
When you view your inbox through the web interface or click the "Get Mail" button on your email
|
||||
client, two things happen: New downloaded emails are shown, if there are any, and the I2P-Bote
|
||||
network is contacted to see if more emails are waiting to be downloaded.
|
||||
|
||||
5. The Configuration File
|
120
history.txt
@ -1,6 +1,126 @@
|
||||
I2P-Bote Version History
|
||||
------------------------
|
||||
|
||||
0.4.1 (Released on Sep 12, 2015)
|
||||
* Fixed bugs:
|
||||
o ConcurrentModificationException errors in logs
|
||||
o User guide and FAQ not loading translations
|
||||
|
||||
0.4 (Released on Aug 21, 2015)
|
||||
* Fixed bugs:
|
||||
o Email checking would get stuck if no new mail was found
|
||||
o "Last checked" time was inconsistent for manual checks
|
||||
o Anonymous emails would never send
|
||||
* Removed build number from version
|
||||
* Skipped 0.3.* series
|
||||
o 0.3.1 is less than 0.3-b195; would need to go to 0.3.196
|
||||
|
||||
0.3 (Released on Aug 15, 2015)
|
||||
* New default theme based on Material design
|
||||
* New features:
|
||||
o Exclude individual identities from global email checking
|
||||
o Manual per-identity email checking
|
||||
o Import and export identities
|
||||
* Strip prefixes, spaces and newlines from email destinations (to better
|
||||
handle destinations pasted from different sources). Supported prefixes:
|
||||
o mailto:
|
||||
o bote:
|
||||
o i2pbote:
|
||||
* Translations for user guide and FAQ
|
||||
* Use I2P XSSFilter on inputs
|
||||
* Bundle BouncyCastle 1.51 crypto provider
|
||||
* In-app update notification removed
|
||||
* IMAP temporarily disabled due to bug
|
||||
* Bug fixes
|
||||
|
||||
0.2.10 (Released on Jul 23, 2014)
|
||||
* Vanity destinations
|
||||
* Security fix related to ElGamal email destinations
|
||||
* IMAP fixes
|
||||
* "After merging, IndexPacket is too big..." error fixed
|
||||
* Numerous fixes and enhancements by str4d
|
||||
|
||||
0.2.9 (Released on Feb 7, 2014)
|
||||
* Experimental SMTP and IMAP support
|
||||
* UI and IMAP improvements by str4d
|
||||
* Misc. UI improvements
|
||||
|
||||
0.2.8 (Released on Mar 8, 2013)
|
||||
* Fixes and enhancements to the address directory
|
||||
|
||||
0.2.7 (Released on Feb 13, 2013)
|
||||
* Delivery confirmations
|
||||
* Basic distributed address directory
|
||||
* Datagram-only communication, streams no longer used;
|
||||
smaller datagrams for better reliability
|
||||
* More translations
|
||||
* UI Themes
|
||||
* Misc. UI improvements
|
||||
* Bug fixes
|
||||
|
||||
0.2.6 (Released on Apr 26, 2011)
|
||||
* Password encryption of mail folders, identities, and contacts
|
||||
* New translations (in chronological order):
|
||||
o French by albat, redzara and magma
|
||||
o Spanish by mixxy
|
||||
o Dutch by KwukDuck
|
||||
o Portuguese by mixxy
|
||||
o Norwegian by nej
|
||||
o Swedish by hottuna
|
||||
o Chinese by walking
|
||||
o Arabic by hamada
|
||||
* In-app user guide and FAQ in English (by mixxy) and its French translation (by magma)
|
||||
* Availability of updates now displayed in I2P-Bote itself
|
||||
* NTRU encryption / GMSS signatures
|
||||
* Big packets are now sent as streams (see http://trac.i2p2.de/ticket/346)
|
||||
* Fix: Email files not deleted on Windows
|
||||
* Fix: Emails in sent folder and outbox not signed
|
||||
* Fix: Seedless not used if I2P-Bote is ready before Seedless
|
||||
* Minor fixes and enhancements
|
||||
|
||||
0.2.5 (Released on Oct 04, 2010)
|
||||
* Email attachments
|
||||
* Seedless peer exchange
|
||||
* Russian translation by suhr
|
||||
* All generated files are now read/writable by the owner only
|
||||
* I2P-Bote always uses the router console language (if translation available)
|
||||
* The network page now shows peers in b32 for I2P compatibility
|
||||
* Address book and identities are now sorted alphabetically
|
||||
* The "unknown" column has been inverted to a "known" column
|
||||
* Signatures for sent emails are not shown because signatures are not saved
|
||||
* Emails, including attachments, are compressed before sending
|
||||
* Protocol version 4
|
||||
* Improvements and fixes to relaying
|
||||
* Fix for a bug that sometimes made emails to ECC destinations disappear
|
||||
* Many more bugfixes and improvements. Thanks to mixxy and others for testing!
|
||||
|
||||
0.2.4 (Released on Jun 14, 2010)
|
||||
* Elliptic curve encryption
|
||||
* Email can be sent via relays for added anonymity
|
||||
* Experimental gateway (in/outproxy) support
|
||||
* Protocol version 3, fixes two weaknesses
|
||||
* Kademlia replication
|
||||
* Fix: Error when trying to send anonymously
|
||||
|
||||
0.2.3 (Released on May 10, 2010)
|
||||
* Email signatures
|
||||
* Multiple recipients / CC / BCC implemented
|
||||
* A button on the "new email" page for adding a recipient to the address book
|
||||
* Local names for Email Destinations are displayed automatically and
|
||||
take priority over names chosen by senders
|
||||
* Local names for Email Destinations are removed from emails before sending
|
||||
* Sorted mail folders
|
||||
* Outbox functionality; emails are now sent in the background
|
||||
* Sent folder, Trash folder
|
||||
* No more getting the same email over and over again
|
||||
* New options on the Settings page:
|
||||
o Enable/disable sending of date/time
|
||||
o Enable/disable localization of text that recipients see, such as "Re:"
|
||||
o UI language
|
||||
* Misc UI enhancements
|
||||
* Fix for a bug that caused excessive CPU usage
|
||||
* Fix for a bug that hid the first row in a table (identities, inbox, etc.)
|
||||
|
||||
0.2.2 (Released on Mar 22, 2010)
|
||||
* German translation
|
||||
* Automatic mail checking is now user-configurable
|
||||
|
18
jsp2po.sh
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Extracts strings from <ib:message> tags and prints them
|
||||
# to stdout in .po format (the .po header is not printed).
|
||||
# Limitations:
|
||||
# * Only <ib:message key="....."/> and <ib:message key='.....'/>
|
||||
# are supported, <ib:message>.....</ib:message> is not.
|
||||
# * The key="....." parameter must be on one line.
|
||||
#
|
||||
# How it works:
|
||||
# * The while loop greps all ib:message lines, extracts the
|
||||
# "key" parameter, and prints to stdout
|
||||
# * The first awk removes duplicate message keys
|
||||
# * the second awk makes a .po entry for each message key
|
||||
#
|
||||
find "$@" -name '*.jsp' -o -name '*.tag' | while read i; do
|
||||
echo "#################### $i ####################";
|
||||
grep "<ib:message key=\"" "$i" | sed "s#.*\<ib:message key=\""## | sed "s#\".*##"; grep "<ib:message key='" "$i" | sed "s#.*\<ib:message key='"## | sed "s#'.*##" | sort
|
||||
done | awk ' !x[$0]++' | awk '{ if (index($0, "###")==0) { print ("msgid \""$0"\""); print ("msgstr \"\""); print(""); } else { print $0; } }';
|
BIN
lib/flexi-gmss-1.7p1.jar
Normal file
BIN
lib/jcommon-1.0.23.jar
Normal file
BIN
lib/jfreechart-1.0.19.jar
Normal file
BIN
lib/lzma-9.20.jar
Normal file
BIN
lib/ntruenc-1.2.jar
Normal file
BIN
lib/scrypt-1.4.0.jar
Normal file
680
license.txt
@ -1,674 +1,10 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
LICENSES
|
||||
--------
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
This software is licensed under the GPL version 3 (see licenses/GPLv3.txt),
|
||||
except for:
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
- bcprov-jdk15on-152.jar which is licensed under the Bouncy Castle License
|
||||
(see licenses/BouncyCastle.txt).
|
||||
- nl.jteam.tls.StrongTls which is licensed under the Apache License, Version
|
||||
2.0 (see licenses/LICENSE-Apache2.0.txt).
|
||||
|
22
licenses/BouncyCastle.txt
Normal file
@ -0,0 +1,22 @@
|
||||
License
|
||||
|
||||
Copyright (c) 2000 - 2009 The Legion Of The Bouncy Castle
|
||||
(http://www.bouncycastle.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
674
licenses/GPLv3.txt
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
202
licenses/LICENSE-Apache2.0.txt
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1326
locale/messages_ar.po
Normal file
1332
locale/messages_cs.po
Normal file
1356
locale/messages_en.po
Normal file
1392
locale/messages_es.po
Normal file
1317
locale/messages_fi.po
Normal file
1378
locale/messages_fr.po
Normal file
1332
locale/messages_hu.po
Normal file
1352
locale/messages_id.po
Normal file
1369
locale/messages_it.po
Normal file
1343
locale/messages_ja.po
Normal file
1347
locale/messages_nb.po
Normal file
1366
locale/messages_nl.po
Normal file
1363
locale/messages_pl.po
Normal file
1366
locale/messages_pt.po
Normal file
1339
locale/messages_pt_BR.po
Normal file
1356
locale/messages_ro.po
Normal file
1367
locale/messages_ru.po
Normal file
1353
locale/messages_sk.po
Normal file
1357
locale/messages_sv.po
Normal file
1326
locale/messages_uk.po
Normal file
1325
locale/messages_vi.po
Normal file
1335
locale/messages_zh.po
Normal file
113
nbproject/project.xml
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.ant.freeform</type>
|
||||
<configuration>
|
||||
<general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
|
||||
<name>I2P-Bote</name>
|
||||
</general-data>
|
||||
<general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
|
||||
<!-- Do not use Project Properties customizer when editing this file manually. -->
|
||||
<name>I2P-Bote</name>
|
||||
<properties/>
|
||||
<folders>
|
||||
<source-folder>
|
||||
<label>I2P-Bote</label>
|
||||
<location>.</location>
|
||||
<encoding>UTF-8</encoding>
|
||||
</source-folder>
|
||||
<source-folder>
|
||||
<label>WebContent</label>
|
||||
<type>doc_root</type>
|
||||
<location>WebContent</location>
|
||||
</source-folder>
|
||||
<source-folder>
|
||||
<label>WEB-INF</label>
|
||||
<type>web_inf</type>
|
||||
<location>WebContent/WEB-INF</location>
|
||||
</source-folder>
|
||||
<source-folder>
|
||||
<label>test</label>
|
||||
<type>java</type>
|
||||
<location>test</location>
|
||||
<encoding>UTF-8</encoding>
|
||||
</source-folder>
|
||||
<source-folder>
|
||||
<label>src</label>
|
||||
<type>java</type>
|
||||
<location>src</location>
|
||||
<encoding>UTF-8</encoding>
|
||||
</source-folder>
|
||||
</folders>
|
||||
<ide-actions>
|
||||
<action name="build">
|
||||
<target>all</target>
|
||||
</action>
|
||||
<action name="clean">
|
||||
<target>clean</target>
|
||||
</action>
|
||||
<action name="test">
|
||||
<target>junit</target>
|
||||
</action>
|
||||
<action name="rebuild">
|
||||
<target>clean</target>
|
||||
<target>all</target>
|
||||
</action>
|
||||
</ide-actions>
|
||||
<export>
|
||||
<type>folder</type>
|
||||
<location>ant_build/classes</location>
|
||||
<build-target>all</build-target>
|
||||
</export>
|
||||
<view>
|
||||
<items>
|
||||
<source-folder style="tree">
|
||||
<label>Web Pages</label>
|
||||
<location>WebContent</location>
|
||||
</source-folder>
|
||||
<source-folder style="tree">
|
||||
<label>WEB-INF Content</label>
|
||||
<location>WebContent/WEB-INF</location>
|
||||
</source-folder>
|
||||
<source-folder style="packages">
|
||||
<label>test</label>
|
||||
<location>test</location>
|
||||
</source-folder>
|
||||
<source-folder style="packages">
|
||||
<label>src</label>
|
||||
<location>src</location>
|
||||
</source-folder>
|
||||
<source-file>
|
||||
<location>build.xml</location>
|
||||
</source-file>
|
||||
</items>
|
||||
<context-menu>
|
||||
<ide-action name="build"/>
|
||||
<ide-action name="rebuild"/>
|
||||
<ide-action name="clean"/>
|
||||
<ide-action name="test"/>
|
||||
</context-menu>
|
||||
</view>
|
||||
<subprojects/>
|
||||
</general-data>
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1">
|
||||
<compilation-unit>
|
||||
<package-root>test</package-root>
|
||||
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-jdk15on-152.jar:ant_build/classes:/usr/local/netbeans-6.5/platform9/modules/ext/junit-4.5.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
|
||||
<source-level>1.5</source-level>
|
||||
</compilation-unit>
|
||||
<compilation-unit>
|
||||
<package-root>src</package-root>
|
||||
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-jdk15on-152.jar:ant_build/classes:../i2p/apps/streaming/java/build/streaming.jar:../i2p/apps/ministreaming/java/build/mstreaming.jar:../i2p/apps/routerconsole/java/build/routerconsole.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
|
||||
<built-to>ant_build/classes</built-to>
|
||||
<source-level>1.5</source-level>
|
||||
</compilation-unit>
|
||||
</java-data>
|
||||
<web-data xmlns="http://www.netbeans.org/ns/freeform-project-web/1">
|
||||
<web-module>
|
||||
<doc-root>WebContent</doc-root>
|
||||
<classpath/>
|
||||
<j2ee-spec-level>1.5</j2ee-spec-level>
|
||||
</web-module>
|
||||
</web-data>
|
||||
</configuration>
|
||||
</project>
|
@ -1,12 +1,44 @@
|
||||
name=i2pbote
|
||||
signer=HungryHobo@mail.i2p
|
||||
consoleLinkName=I2P-Bote
|
||||
consoleLinkName_de=I2P-Bote
|
||||
signer=str4d@mail.i2p
|
||||
consoleLinkName=SecureMail
|
||||
consoleLinkName_de=Sichere.Mail
|
||||
consoleLinkName_nl=Beveiligde Mail
|
||||
consoleLinkName_fr=CourrierSécurisé
|
||||
consoleLinkName_es=CorreoSeguro
|
||||
consoleLinkName_pt=CorreioSeguro
|
||||
consoleLinkName_ru=Безопасная почта
|
||||
consoleLinkName_no=SecureMail #SikkerPost
|
||||
consoleLinkName_sv=SäkerPost
|
||||
consoleLinkName_zh=安全电邮
|
||||
consoleLinkName_ar=بريد الكتروني الآمن
|
||||
consoleLinkTooltip=Decentralized secure email
|
||||
consoleLinkTooltip_de=Dezentrale, sichere Mailanwendung
|
||||
consoleLinkTooltip_nl=Gedecentraliseerde beveiligde email
|
||||
consoleLinkTooltip_fr=Courrier sécurisé et décentralisé
|
||||
consoleLinkTooltip_es=Correo electrónico seguro y descentralizado
|
||||
consoleLinkTooltip_pt=Correio eletrônico seguro e descentralizado
|
||||
consoleLinkTooltip_ru=Безопасная распределённая почта
|
||||
consoleLinkTooltip_no=Desentralisert sikker epost
|
||||
consoleLinkTooltip_sv=Decentraliserad säker e-post
|
||||
consoleLinkTooltip_zh=安全分布式电子邮件
|
||||
consoleLinkTooltip_ar=بريد الكتروني الآمن و الغير متمركز
|
||||
consoleLinkURL=/i2pbote/index.jsp
|
||||
websiteURL=http://i2pbote.i2p/
|
||||
updateURL=http://i2pbote.i2p/i2pbote-update.xpi2p
|
||||
description=Decentralized email
|
||||
description_de=Dezentrale Mailanwendung
|
||||
console-icon=/themes/material/icon.png
|
||||
websiteURL=http://bote.i2p/
|
||||
updateURL=http://bote.i2p/i2pbote-update.xpi2p
|
||||
updateURL.su3=http://bote.i2p/i2pbote-update.su3
|
||||
description=Decentralized secure email
|
||||
description_de=Dezentrale, sichere Mailanwendung
|
||||
description_nl=Gedecentraliseerde beveiligde email
|
||||
description_fr=Courrier sécurisé et décentralisé
|
||||
description_es=Correo electrónico seguro y descentralizado
|
||||
description_pt=Correio eletrônico seguro e descentralizado
|
||||
description_ru=Безопасная распределённая почта
|
||||
description_no=Desentralisert sikker epost
|
||||
description_sv=Decentraliserad säker e-post
|
||||
description_zh=安全分布式电子邮件
|
||||
description_ar=بريد الكتروني الآمن و الغير متمركز
|
||||
license=GPL V3
|
||||
min-java-version=1.6
|
||||
author=HungryHobo@mail.i2p
|
||||
min-i2p-version=0.9.18
|
||||
author=str4d@mail.i2p
|
||||
|
@ -1 +1 @@
|
||||
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/mailapi.jar
|
||||
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/i2pbote.jar,$PLUGIN/lib/mailapi-1.5.4.jar,$PLUGIN/lib/bcprov-jdk15on-152.jar,$PLUGIN/lib/flexi-gmss-1.7p1.jar,$PLUGIN/lib/ntruenc-1.2.jar,$PLUGIN/lib/scrypt-1.4.0.jar,$PLUGIN/lib/lzma-9.20.jar,$PLUGIN/lib/apache-james-mailbox-api-0.6-20150508.040939-710.jar,$PLUGIN/lib/apache-james-mailbox-store-0.6-20150508.041003-704.jar,$PLUGIN/lib/apache-mime4j-core-0.8.0-20150617.024907-738.jar,$PLUGIN/lib/commons-codec-1.7.jar,$PLUGIN/lib/commons-collections-3.2.1.jar,$PLUGIN/lib/commons-configuration-1.9.jar,$PLUGIN/lib/commons-io-2.4.jar,$PLUGIN/lib/commons-lang-2.6.jar,$PLUGIN/lib/james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-util-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/jcommon-1.0.23.jar,$PLUGIN/lib/jfreechart-1.0.19.jar,$PLUGIN/lib/jutf7-1.0.0.jar,$PLUGIN/lib/log4j-1.2.17.jar,$PLUGIN/lib/netty-3.3.1.Final.jar,$PLUGIN/lib/protocols-api-1.6.4-20150617.121129-1080.jar,$PLUGIN/lib/protocols-imap-1.6.4-20150617.121245-927.jar,$PLUGIN/lib/protocols-netty-1.6.4-20150617.121137-1044.jar,$PLUGIN/lib/slf4j-api-1.7.2.jar,$PLUGIN/lib/slf4j-log4j12-1.7.2.jar,$PLUGIN/lib/subethasmtp-3.1.7.jar
|
||||
|
207
src/build/java/i2p/bote/ant/JspStrings.java
Normal file
@ -0,0 +1,207 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.ant;
|
||||
|
||||
import i2p.bote.Util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A command line program that extracts strings from <ib:message> tags and prints them
|
||||
* to stdout in .po format (the .po header is not printed).
|
||||
*/
|
||||
public class JspStrings {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length < 1) {
|
||||
System.out.println("Syntax: JspStrings <Directory>");
|
||||
System.out.println();
|
||||
System.out.println("Prints .po entries for the <ib:message> keys in all .jsp");
|
||||
System.out.println("and .tag files in <Directory> and its subdirectories.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
List<PoEntry> poEntries = processDirectory(new File(args[0]));
|
||||
removeDuplicates(poEntries);
|
||||
|
||||
for (PoEntry poEntry: poEntries)
|
||||
print(poEntry);
|
||||
}
|
||||
|
||||
static void removeDuplicates(List<PoEntry> poEntries) {
|
||||
for (int i=poEntries.size()-1; i>=0; i--)
|
||||
for (int j=poEntries.size()-1; j>i; j--) {
|
||||
PoEntry entry1 = poEntries.get(i);
|
||||
PoEntry entry2 = poEntries.get(j);
|
||||
if (entry1!=entry2 && entry1.msgKey.equals(entry2.msgKey))
|
||||
poEntries.remove(entry2);
|
||||
}
|
||||
}
|
||||
|
||||
static void print(PoEntry poEntry) {
|
||||
System.out.println("#: " + poEntry.comment);
|
||||
System.out.println("msgid \"" + poEntry.msgKey + "\"");
|
||||
System.out.println("msgstr \"\"");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
static List<PoEntry> processDirectory(File dir) throws IOException {
|
||||
List<PoEntry> results = new ArrayList<PoEntry>();
|
||||
|
||||
// extract strings from all files in the directory
|
||||
File[] files = dir.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.toLowerCase().endsWith(".jsp") || name.toLowerCase().endsWith(".tag");
|
||||
}
|
||||
});
|
||||
for (File file: files)
|
||||
results.addAll(processFile(file));
|
||||
|
||||
// recurse into subdirectories
|
||||
File[] subdirs = dir.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.isDirectory();
|
||||
}
|
||||
});
|
||||
for (File subdir: subdirs)
|
||||
results.addAll(processDirectory(subdir));
|
||||
return results;
|
||||
}
|
||||
|
||||
static List<PoEntry> processFile(File file) throws IOException {
|
||||
FileInputStream inputStream = new FileInputStream(file);
|
||||
BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
// Read the file into a string
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
while (true) {
|
||||
String line = inputReader.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
if (strBuilder.length() > 0)
|
||||
strBuilder = strBuilder.append(System.getProperty("line.separator"));
|
||||
strBuilder = strBuilder.append(line);
|
||||
}
|
||||
inputStream.close();
|
||||
String fileContents = strBuilder.toString();
|
||||
|
||||
String[] tags = fileContents.split("<ib:message");
|
||||
|
||||
List<String> msgKeys = new ArrayList<String>();
|
||||
for (int i=1; i<tags.length; i++) {
|
||||
String tag = tags[i];
|
||||
if (!shouldSkip(tag)) {
|
||||
String key = extract(tag);
|
||||
if (key != null)
|
||||
msgKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
List<PoEntry> entries = new ArrayList<PoEntry>();
|
||||
entries.addAll(PoEntry.create(msgKeys, file));
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a message key from a ib:message tag
|
||||
* @param tag a ib:message tag minus the <ib:message part at the beginning
|
||||
* @return
|
||||
*/
|
||||
static String extract(String tag) {
|
||||
if (tag.contains(" key=")) // format is <ib:message key="foobar" .../> ...
|
||||
return extractFromKeyAttribute(tag);
|
||||
else // format is <ib:message ...>foobar</ib:message> ...
|
||||
return extractFromTagBody(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the text between <ib:message> and </ib:message>
|
||||
* @param tag a ib:message tag minus the <ib:message part at the beginning
|
||||
*/
|
||||
static String extractFromTagBody(String tag) {
|
||||
int gtIndex = tag.indexOf(">");
|
||||
tag = tag.substring(gtIndex + 1);
|
||||
int endIdx = tag.indexOf("</ib:message");
|
||||
if (endIdx < 0) {
|
||||
System.err.println("No \"</ib:message\" end tag in string: <" + tag + ">");
|
||||
return null;
|
||||
}
|
||||
String str = tag.substring(0, endIdx);
|
||||
// convert multiple whitespaces in a row to a single space, remove leading and trailing whitespace
|
||||
str = Util.removeExtraWhitespace(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
/** Extracts the values of the "key" attribute */
|
||||
static String extractFromKeyAttribute(String string) {
|
||||
String keyAttrSQ = "key='";
|
||||
String keyAttrDQ = "key=\"";
|
||||
int keyAttrLen = keyAttrDQ.length();
|
||||
|
||||
int startIdxSQ = string.indexOf(keyAttrSQ);
|
||||
int endIdxSQ = string.indexOf("'", startIdxSQ+keyAttrLen);
|
||||
int startIdxDQ = string.indexOf(keyAttrDQ);
|
||||
int endIdxDQ = string.indexOf("\"", startIdxDQ+keyAttrLen);
|
||||
|
||||
if (startIdxSQ>=0 && (startIdxSQ<startIdxDQ || startIdxDQ<0) && endIdxSQ>=0)
|
||||
return string.substring(startIdxSQ+keyAttrLen, endIdxSQ);
|
||||
else if (startIdxDQ>=0 && (startIdxDQ<startIdxSQ || startIdxSQ<0) && endIdxDQ>=0)
|
||||
return string.substring(startIdxDQ+keyAttrLen, endIdxDQ);
|
||||
else {
|
||||
System.err.println("Expected a string containing key=\"...\" or key='...', got " + string);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns <code>true</code> if a ib:message tag has the noextract attribute set to <code>true</code>. */
|
||||
static boolean shouldSkip(String tag) {
|
||||
tag = tag.replaceAll("\\s+", "");
|
||||
return tag.contains("noextract=\"true\"") || tag.contains("noextract='true'");
|
||||
}
|
||||
|
||||
static class PoEntry {
|
||||
String msgKey;
|
||||
String comment;
|
||||
|
||||
static List<PoEntry> create(List<String> msgKeys, File file) {
|
||||
List<PoEntry> poEntries = new ArrayList<PoEntry>();
|
||||
for (String msgKey: msgKeys) {
|
||||
PoEntry entry = new PoEntry();
|
||||
entry.msgKey = msgKey;
|
||||
entry.comment = file.toString();
|
||||
poEntries.add(entry);
|
||||
}
|
||||
return poEntries;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,15 +19,13 @@
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.network;
|
||||
package i2p.bote.ant;
|
||||
|
||||
import i2p.bote.packet.I2PBotePacket;
|
||||
import i2p.bote.I2PBote;
|
||||
|
||||
public interface SendQueuePacketListener {
|
||||
public class PrintAppVersion {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
void packetSent(I2PBotePacket packet);
|
||||
public static void main(String[] args) {
|
||||
System.out.println(I2PBote.getAppVersion());
|
||||
}
|
||||
}
|
107
src/build/java/i2p/bote/ant/SearchAndInsert.java
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.ant;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Searches a text file for a string and adds text before
|
||||
* or after the first occurrence of the search string.
|
||||
*/
|
||||
public class SearchAndInsert {
|
||||
enum Position {BEFORE, AFTER};
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length < 4) {
|
||||
System.out.println("Syntax: SearchAndInsert [-after|-before] <inputFile> <outputFile> <key> <newTextFile>");
|
||||
System.out.println();
|
||||
System.out.println("Searches a text file for a string and adds text before or after");
|
||||
System.out.println("the first occurrence of the search string. The new text is read");
|
||||
System.out.println("from a file.");
|
||||
System.out.println("The default is to insert after the search string.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
int argIndex = 0;
|
||||
Position position = Position.AFTER;
|
||||
if ("-before".equals(args[0]) || "-after".equals(args[0])) {
|
||||
argIndex++;
|
||||
if ("-before".equals(args[0]))
|
||||
position = Position.BEFORE;
|
||||
}
|
||||
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(args[argIndex++]));
|
||||
writer = new BufferedWriter(new FileWriter(args[argIndex++]));
|
||||
|
||||
String searchString = args[argIndex++];
|
||||
String newTextFile = args[argIndex];
|
||||
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
boolean match = line.contains(searchString);
|
||||
if (match && position==Position.BEFORE) {
|
||||
write(writer, newTextFile);
|
||||
writer.newLine();
|
||||
}
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
if (match && position==Position.AFTER) {
|
||||
write(writer, newTextFile);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (reader != null)
|
||||
reader.close();
|
||||
if (writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void write(BufferedWriter writer, String filename) throws IOException {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(filename));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
writer.write(line);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (reader != null)
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Update messages_xx.po and messages_xx.class files,
|
||||
# from both java and jsp sources.
|
||||
# Requires installed programs xgettext, msgfmt, msgmerge, find,
|
||||
# plus everything jsp2po.sh depends on: grep, sed, awk, sort, and bash.
|
||||
# Requires installed programs xgettext, msgfmt, msgmerge, msguniq, find,
|
||||
# and the Java class i2p.bote.ant.JspStrings.
|
||||
# On Linux, the programs xgettext and msg* can be found in the gettext package.
|
||||
#
|
||||
# usage:
|
||||
# bundle-messages.sh (generates the resource bundle from the .po file)
|
||||
@ -10,6 +12,7 @@
|
||||
#
|
||||
# zzz - public domain
|
||||
#
|
||||
JAVA=java
|
||||
CLASS=i2p.bote.locale.Messages
|
||||
TMPFILE=ant_build/javafiles.txt
|
||||
export TZ=UTC
|
||||
@ -19,15 +22,29 @@ then
|
||||
POUPDATE=1
|
||||
fi
|
||||
|
||||
# on windows, one must specify the path of commnad find
|
||||
# since windows has its own retarded version of find.
|
||||
if which find|grep -q -i windows ; then
|
||||
export PATH=.:/bin:/usr/local/bin:$PATH
|
||||
fi
|
||||
# Fast mode - update ondemond
|
||||
echo setting the environment variable LG2={LangCode}
|
||||
echo will limit .po file update to the language specified by {LangCode}.
|
||||
|
||||
# add ../java/ so the refs will work in the po file
|
||||
JPATHS="src"
|
||||
JSPPATHS="WebContent"
|
||||
JPATHS="src/main/java"
|
||||
JSPPATHS="src/main/webapp"
|
||||
for i in locale/messages_*.po
|
||||
do
|
||||
# get language
|
||||
LG=${i#locale/messages_}
|
||||
LG=${LG%.po}
|
||||
|
||||
# skip, if specified
|
||||
if [ $LG2 ]; then
|
||||
[ $LG != $LG2 ] && continue || echo INFO: Language update is set to [$LG2] only.
|
||||
fi
|
||||
|
||||
if [ "$POUPDATE" = "1" ]
|
||||
then
|
||||
# make list of java files newer than the .po file
|
||||
@ -63,8 +80,15 @@ do
|
||||
fi
|
||||
|
||||
# extract strings from jsp files
|
||||
./jsp2po.sh $JSPPATHS >> ${i}t
|
||||
$JAVA -cp ant_build/classes:$I2P/lib/i2p.jar i2p.bote.ant.JspStrings $JSPPATHS >> ${i}t
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - JspStrings failed, not updating translations'
|
||||
rm -f ${i}t
|
||||
break
|
||||
fi
|
||||
|
||||
msguniq -o ${i}t ${i}t
|
||||
msgmerge -U --backup=none $i ${i}t
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
@ -77,15 +101,19 @@ do
|
||||
touch $i
|
||||
fi
|
||||
|
||||
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||
if [ "$LG" != "en" ]
|
||||
then
|
||||
# only generate for non-source language
|
||||
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||
|
||||
# convert to class files in ant_build/classes
|
||||
msgfmt --java --statistics -r $CLASS -l $LG -d ant_build/classes $i
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - msgfmt failed, not updating translations'
|
||||
break
|
||||
fi
|
||||
# convert to class files in ant_build/classes
|
||||
msgfmt --java --statistics -r $CLASS -l $LG -d ant_build/classes $i
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - msgfmt failed, not updating translations'
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
rm -f $TMPFILE
|
||||
# todo: return failure
|
@ -1,272 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class Configuration {
|
||||
private static final long serialVersionUID = -6318245413106186095L;
|
||||
private static final String I2P_BOTE_SUBDIR = "i2pbote"; // relative to the I2P app dir
|
||||
private static final String CONFIG_FILE_NAME = "i2pbote.config";
|
||||
private static final String DEST_KEY_FILE_NAME = "local_dest.key";
|
||||
private static final String PEER_FILE_NAME = "peers.txt";
|
||||
private static final String IDENTITIES_FILE_NAME = "identities.txt";
|
||||
private static final String ADDRESS_BOOK_FILE_NAME = "addressBook.txt";
|
||||
private static final String OUTBOX_DIR = "outbox"; // relative to I2P_BOTE_SUBDIR
|
||||
private static final String OUTBOX_SUBDIR_LOCAL = "local"; // relative to OUTBOX_DIR
|
||||
private static final String OUTBOX_SUBDIR_RELAY = "relay"; // relative to OUTBOX_DIR
|
||||
private static final String INCOMPLETE_SUBDIR = "incomplete"; // relative to I2P_BOTE_SUBDIR
|
||||
private static final String EMAIL_DHT_SUBDIR = "dht_email_pkt"; // relative to I2P_BOTE_SUBDIR
|
||||
private static final String INDEX_PACKET_DHT_SUBDIR = "dht_index_pkt"; // relative to I2P_BOTE_SUBDIR
|
||||
private static final String INBOX_SUBDIR = "inbox"; // relative to I2P_BOTE_SUBDIR
|
||||
|
||||
// Parameter names in the config file
|
||||
private static final String PARAMETER_REDUNDANCY = "redundancy";
|
||||
private static final String PARAMETER_STORAGE_SPACE_INBOX = "storageSpaceInbox";
|
||||
private static final String PARAMETER_STORAGE_SPACE_RELAY = "storageSpaceRelay";
|
||||
private static final String PARAMETER_STORAGE_TIME = "storageTime";
|
||||
private static final String PARAMETER_MAX_FRAGMENT_SIZE = "maxFragmentSize";
|
||||
private static final String PARAMETER_HASHCASH_STRENGTH = "hashCashStrength";
|
||||
private static final String PARAMETER_SMTP_PORT = "smtpPort";
|
||||
private static final String PARAMETER_POP3_PORT = "pop3Port";
|
||||
private static final String PARAMETER_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL = "maxConcurIdCheckMail";
|
||||
private static final String PARAMETER_AUTO_MAIL_CHECK = "autoMailCheckEnabled";
|
||||
private static final String PARAMETER_MAIL_CHECK_INTERVAL = "mailCheckInterval";
|
||||
|
||||
// Defaults for each parameter
|
||||
private static final int DEFAULT_REDUNDANCY = 2;
|
||||
private static final int DEFAULT_STORAGE_SPACE_INBOX = 1024 * 1024 * 1024;
|
||||
private static final int DEFAULT_STORAGE_SPACE_RELAY = 100 * 1024 * 1024;
|
||||
private static final int DEFAULT_STORAGE_TIME = 31; // in days
|
||||
private static final int DEFAULT_MAX_FRAGMENT_SIZE = 10 * 1024 * 1024; // the maximum size one email fragment can be, in bytes
|
||||
private static final int DEFAULT_HASHCASH_STRENGTH = 10;
|
||||
private static final int DEFAULT_SMTP_PORT = 7661;
|
||||
private static final int DEFAULT_POP3_PORT = 7662;
|
||||
private static final int DEFAULT_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL = 10;
|
||||
private static final boolean DEFAULT_AUTO_MAIL_CHECK = true;
|
||||
private static final int DEFAULT_MAIL_CHECK_INTERVAL = 30; // in minutes
|
||||
|
||||
private Log log = new Log(Configuration.class);
|
||||
private Properties properties;
|
||||
private File i2pBoteDir;
|
||||
private File configFile;
|
||||
|
||||
/**
|
||||
* Reads configuration settings from the <code>I2P_BOTE_SUBDIR</code> subdirectory under
|
||||
* the I2P application directory. The I2P application directory can be changed via the
|
||||
* <code>i2p.dir.app</code> system property.
|
||||
*
|
||||
* Logging is done through the I2P logger. I2P reads the log configuration from the
|
||||
* <code>logger.config</code> file whose location is determined by the
|
||||
* <code>i2p.dir.config</code> system property.
|
||||
* @return
|
||||
*/
|
||||
public Configuration() {
|
||||
properties = new Properties();
|
||||
|
||||
// get the I2PBote directory and make sure it exists
|
||||
i2pBoteDir = getI2PBoteDirectory();
|
||||
if (!i2pBoteDir.exists() && !i2pBoteDir.mkdirs())
|
||||
log.error("Cannot create directory: <" + i2pBoteDir.getAbsolutePath() + ">");
|
||||
|
||||
// read the configuration file
|
||||
configFile = new File(i2pBoteDir, CONFIG_FILE_NAME);
|
||||
boolean configurationLoaded = false;
|
||||
if (configFile.exists()) {
|
||||
log.debug("Loading config file <" + configFile.getAbsolutePath() + ">");
|
||||
|
||||
try {
|
||||
DataHelper.loadProps(properties, configFile);
|
||||
configurationLoaded = true;
|
||||
} catch (IOException e) {
|
||||
log.error("Error loading configuration file <" + configFile.getAbsolutePath() + ">", e);
|
||||
}
|
||||
}
|
||||
if (!configurationLoaded)
|
||||
log.info("Can't read configuration file <" + configFile.getAbsolutePath() + ">, using default settings.");
|
||||
}
|
||||
|
||||
public File getDestinationKeyFile() {
|
||||
return new File(i2pBoteDir, DEST_KEY_FILE_NAME);
|
||||
}
|
||||
|
||||
public File getPeerFile() {
|
||||
return new File(i2pBoteDir, PEER_FILE_NAME);
|
||||
}
|
||||
|
||||
public File getIdentitiesFile() {
|
||||
return new File(i2pBoteDir, IDENTITIES_FILE_NAME);
|
||||
}
|
||||
|
||||
public File getAddressBookFile() {
|
||||
return new File(i2pBoteDir, ADDRESS_BOOK_FILE_NAME);
|
||||
}
|
||||
|
||||
public File getLocalOutboxDir() {
|
||||
return new File(getOutboxBaseDir(), OUTBOX_SUBDIR_LOCAL);
|
||||
}
|
||||
|
||||
public File getRelayOutboxDir() {
|
||||
return new File(getOutboxBaseDir(), OUTBOX_SUBDIR_RELAY);
|
||||
}
|
||||
|
||||
private File getOutboxBaseDir() {
|
||||
return new File(i2pBoteDir, OUTBOX_DIR);
|
||||
}
|
||||
|
||||
public File getInboxDir() {
|
||||
return new File(i2pBoteDir, INBOX_SUBDIR);
|
||||
}
|
||||
|
||||
public File getIncompleteDir() {
|
||||
return new File(i2pBoteDir, INCOMPLETE_SUBDIR);
|
||||
}
|
||||
|
||||
public File getEmailDhtStorageDir() {
|
||||
return new File(i2pBoteDir, EMAIL_DHT_SUBDIR);
|
||||
}
|
||||
|
||||
public File getIndexPacketDhtStorageDir() {
|
||||
return new File(i2pBoteDir, INDEX_PACKET_DHT_SUBDIR);
|
||||
}
|
||||
|
||||
private static File getI2PBoteDirectory() {
|
||||
// the parent directory of the I2PBote directory ($HOME or the value of the i2p.dir.app property)
|
||||
File i2pAppDir = I2PAppContext.getGlobalContext().getAppDir();
|
||||
|
||||
return new File(i2pAppDir, I2P_BOTE_SUBDIR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the configuration
|
||||
* @param configFile
|
||||
*/
|
||||
public void save() {
|
||||
log.debug("Saving config file <" + configFile.getAbsolutePath() + ">");
|
||||
try {
|
||||
DataHelper.storeProps(properties, configFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Cannot save configuration to file <" + configFile.getAbsolutePath() + ">", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of relays to use for sending and receiving email. Zero is a legal value.
|
||||
* @return
|
||||
*/
|
||||
public int getRedundancy() {
|
||||
return getIntParameter(PARAMETER_REDUNDANCY, DEFAULT_REDUNDANCY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum size (in bytes) the inbox can take up.
|
||||
* @return
|
||||
*/
|
||||
public int getStorageSpaceInbox() {
|
||||
return getIntParameter(PARAMETER_STORAGE_SPACE_INBOX, DEFAULT_STORAGE_SPACE_INBOX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum size (in bytes) all messages stored for relaying can take up.
|
||||
* @return
|
||||
*/
|
||||
public int getStorageSpaceRelay() {
|
||||
return getIntParameter(PARAMETER_STORAGE_SPACE_RELAY, DEFAULT_STORAGE_SPACE_RELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time (in milliseconds) after which an email is deleted from the outbox if it cannot be sent / relayed.
|
||||
* @return
|
||||
*/
|
||||
public long getStorageTime() {
|
||||
return 24L * 3600 * 1000 * getIntParameter(PARAMETER_STORAGE_TIME, DEFAULT_STORAGE_TIME);
|
||||
}
|
||||
|
||||
public int getMaxFragmentSize() {
|
||||
return getIntParameter(PARAMETER_MAX_FRAGMENT_SIZE, DEFAULT_MAX_FRAGMENT_SIZE);
|
||||
}
|
||||
|
||||
public int getHashCashStrength() {
|
||||
return getIntParameter(PARAMETER_HASHCASH_STRENGTH, DEFAULT_HASHCASH_STRENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of email identities to retrieve new emails for at a time.
|
||||
* @return
|
||||
*/
|
||||
public int getMaxConcurIdCheckMail() {
|
||||
return getIntParameter(PARAMETER_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL, DEFAULT_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL);
|
||||
}
|
||||
|
||||
public void setAutoMailCheckEnabled(boolean enabled) {
|
||||
properties.setProperty(PARAMETER_AUTO_MAIL_CHECK, new Boolean(enabled).toString());
|
||||
}
|
||||
|
||||
public boolean isAutoMailCheckEnabled() {
|
||||
return getBooleanParameter(PARAMETER_AUTO_MAIL_CHECK, DEFAULT_AUTO_MAIL_CHECK);
|
||||
}
|
||||
|
||||
public void setMailCheckInterval(int minutes) {
|
||||
properties.setProperty(PARAMETER_MAIL_CHECK_INTERVAL, new Integer(minutes).toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of minutes the application should wait before automatically
|
||||
* checking for mail.
|
||||
* @return
|
||||
*/
|
||||
public int getMailCheckInterval() {
|
||||
return getIntParameter(PARAMETER_MAIL_CHECK_INTERVAL, DEFAULT_MAIL_CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
private boolean getBooleanParameter(String parameterName, boolean defaultValue) {
|
||||
String stringValue = properties.getProperty(parameterName);
|
||||
if ("true".equalsIgnoreCase(stringValue) || "yes".equalsIgnoreCase(stringValue) || "on".equalsIgnoreCase(stringValue) || "1".equals(stringValue))
|
||||
return true;
|
||||
else if ("false".equalsIgnoreCase(stringValue) || "no".equalsIgnoreCase(stringValue) || "off".equalsIgnoreCase(stringValue) || "0".equals(stringValue))
|
||||
return false;
|
||||
else {
|
||||
log.warn("<" + stringValue + "> is not a legal value for the boolean parameter <" + parameterName + ">");
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private int getIntParameter(String parameterName, int defaultValue) {
|
||||
String stringValue = properties.getProperty(parameterName);
|
||||
if (stringValue == null)
|
||||
return defaultValue;
|
||||
else
|
||||
try {
|
||||
return new Integer(properties.getProperty(parameterName));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
log.warn("Can't convert value <" + stringValue + "> for parameter <" + parameterName + "> to int, using default.");
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,529 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote;
|
||||
|
||||
import i2p.bote.addressbook.AddressBook;
|
||||
import i2p.bote.email.Email;
|
||||
import i2p.bote.email.EmailDestination;
|
||||
import i2p.bote.email.EmailIdentity;
|
||||
import i2p.bote.email.Identities;
|
||||
import i2p.bote.folder.EmailFolder;
|
||||
import i2p.bote.folder.EmailPacketFolder;
|
||||
import i2p.bote.folder.IncompleteEmailFolder;
|
||||
import i2p.bote.folder.IndexPacketFolder;
|
||||
import i2p.bote.folder.Outbox;
|
||||
import i2p.bote.folder.PacketFolder;
|
||||
import i2p.bote.network.BanList;
|
||||
import i2p.bote.network.BannedPeer;
|
||||
import i2p.bote.network.CheckEmailTask;
|
||||
import i2p.bote.network.DHT;
|
||||
import i2p.bote.network.DhtPeerStats;
|
||||
import i2p.bote.network.I2PPacketDispatcher;
|
||||
import i2p.bote.network.I2PSendQueue;
|
||||
import i2p.bote.network.NetworkStatus;
|
||||
import i2p.bote.network.PeerManager;
|
||||
import i2p.bote.network.kademlia.KademliaDHT;
|
||||
import i2p.bote.packet.EncryptedEmailPacket;
|
||||
import i2p.bote.packet.IndexPacket;
|
||||
import i2p.bote.packet.RelayPacket;
|
||||
import i2p.bote.packet.UnencryptedEmailPacket;
|
||||
import i2p.bote.service.AutoMailCheckTask;
|
||||
import i2p.bote.service.I2PBoteThread;
|
||||
import i2p.bote.service.OutboxProcessor;
|
||||
import i2p.bote.service.POP3Service;
|
||||
import i2p.bote.service.RelayPacketSender;
|
||||
import i2p.bote.service.SMTPService;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* This is the core class of the application. It is implemented as a singleton.
|
||||
*/
|
||||
public class I2PBote {
|
||||
public static final int PROTOCOL_VERSION = 2;
|
||||
private static final String APP_VERSION = "0.2.2";
|
||||
private static final int STARTUP_DELAY = 3; // the number of minutes to wait before connecting to I2P (this gives the router time to get ready)
|
||||
private static volatile I2PBote instance;
|
||||
|
||||
private Log log = new Log(I2PBote.class);
|
||||
private I2PAppContext appContext;
|
||||
private I2PClient i2pClient;
|
||||
private I2PSession i2pSession;
|
||||
private Configuration configuration;
|
||||
private Identities identities;
|
||||
private AddressBook addressBook;
|
||||
private I2PSendQueue sendQueue;
|
||||
private Outbox outbox; // stores outgoing emails for all local users
|
||||
private EmailFolder inbox; // stores incoming emails for all local users
|
||||
private PacketFolder<RelayPacket> relayPacketFolder; // stores email packets we're forwarding for other machines
|
||||
private IncompleteEmailFolder incompleteEmailFolder; // stores email packets addressed to a local user
|
||||
private EmailPacketFolder emailDhtStorageFolder; // stores email packets for other peers
|
||||
private IndexPacketFolder indexPacketDhtStorageFolder; // stores index packets
|
||||
//TODO private PacketFolder<> addressDhtStorageFolder; // stores email address-destination mappings
|
||||
private SMTPService smtpService;
|
||||
private POP3Service pop3Service;
|
||||
private OutboxProcessor outboxProcessor; // reads emails stored in the outbox and sends them
|
||||
private AutoMailCheckTask autoMailCheckTask;
|
||||
private RelayPacketSender relayPacketSender; // reads packets stored in the relayPacketFolder and sends them
|
||||
private DHT dht;
|
||||
private PeerManager peerManager;
|
||||
private ThreadFactory mailCheckThreadFactory;
|
||||
private ExecutorService mailCheckExecutor;
|
||||
private Collection<Future<Boolean>> pendingMailCheckTasks;
|
||||
private long lastMailCheckTime;
|
||||
private ConnectTask connectTask;
|
||||
|
||||
private I2PBote() {
|
||||
Thread.currentThread().setName("I2PBoteMain");
|
||||
|
||||
appContext = new I2PAppContext();
|
||||
i2pClient = I2PClientFactory.createClient();
|
||||
configuration = new Configuration();
|
||||
|
||||
mailCheckThreadFactory = Util.createThreadFactory("ChkMailTask", CheckEmailTask.THREAD_STACK_SIZE);
|
||||
|
||||
identities = new Identities(configuration.getIdentitiesFile());
|
||||
addressBook = new AddressBook(configuration.getAddressBookFile());
|
||||
initializeFolderAccess();
|
||||
|
||||
// The rest of the initialization happens in ConnectTask because it needs an I2PSession.
|
||||
// It is done in the background so we don't block the webapp thread.
|
||||
connectTask = new ConnectTask();
|
||||
connectTask.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes objects for accessing emails and packet files on the filesystem.
|
||||
*/
|
||||
private void initializeFolderAccess() {
|
||||
inbox = new EmailFolder(configuration.getInboxDir());
|
||||
outbox = new Outbox(configuration.getLocalOutboxDir());
|
||||
relayPacketFolder = new PacketFolder<RelayPacket>(configuration.getRelayOutboxDir());
|
||||
incompleteEmailFolder = new IncompleteEmailFolder(configuration.getIncompleteDir(), inbox);
|
||||
emailDhtStorageFolder = new EmailPacketFolder(configuration.getEmailDhtStorageDir());
|
||||
indexPacketDhtStorageFolder = new IndexPacketFolder(configuration.getIndexPacketDhtStorageDir());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a {@link I2PSession}, using the I2P destination stored on disk or creating a new I2P
|
||||
* destination if no key file exists.
|
||||
*/
|
||||
private void initializeSession() {
|
||||
Properties sessionProperties = new Properties();
|
||||
sessionProperties.setProperty("inbound.nickname", "I2P-Bote");
|
||||
sessionProperties.setProperty("outbound.nickname", "I2P-Bote");
|
||||
sessionProperties.setProperty("i2cp.gzip", String.valueOf(false)); // most of the data we send is encrypted and therefore uncompressible
|
||||
|
||||
// read the local destination key from the key file if it exists
|
||||
File destinationKeyFile = configuration.getDestinationKeyFile();
|
||||
FileReader fileReader = null;
|
||||
try {
|
||||
fileReader = new FileReader(destinationKeyFile);
|
||||
char[] destKeyBuffer = new char[(int)destinationKeyFile.length()];
|
||||
fileReader.read(destKeyBuffer);
|
||||
byte[] localDestinationKey = Base64.decode(new String(destKeyBuffer));
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(localDestinationKey);
|
||||
i2pSession = i2pClient.createSession(inputStream, sessionProperties);
|
||||
i2pSession.connect();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.debug("Destination key file doesn't exist or isn't readable." + e);
|
||||
} catch (I2PSessionException e) {
|
||||
log.warn("Error creating I2PSession.", e);
|
||||
}
|
||||
finally {
|
||||
if (fileReader != null)
|
||||
try {
|
||||
fileReader.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.debug("Error closing file: <" + destinationKeyFile.getAbsolutePath() + ">" + e);
|
||||
}
|
||||
}
|
||||
|
||||
// if the local destination key can't be read or is invalid, create a new one
|
||||
if (i2pSession == null) {
|
||||
log.debug("Creating new local destination key");
|
||||
try {
|
||||
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
|
||||
i2pClient.createDestination(arrayStream);
|
||||
byte[] localDestinationArray = arrayStream.toByteArray();
|
||||
|
||||
i2pSession = i2pClient.createSession(new ByteArrayInputStream(localDestinationArray), sessionProperties);
|
||||
i2pSession.connect();
|
||||
|
||||
saveLocalDestinationKeys(destinationKeyFile, localDestinationArray);
|
||||
} catch (I2PException e) {
|
||||
log.error("Error creating local destination key or I2PSession.", e);
|
||||
} catch (IOException e) {
|
||||
log.error("Error writing local destination key to file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
Destination localDestination = i2pSession.getMyDestination();
|
||||
log.debug("Local destination key = " + localDestination.toBase64());
|
||||
log.debug("Local destination hash = " + localDestination.calculateHash().toBase64());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes daemon threads, doesn't start them yet.
|
||||
*/
|
||||
private void initializeServices() {
|
||||
I2PPacketDispatcher dispatcher = new I2PPacketDispatcher();
|
||||
i2pSession.addSessionListener(dispatcher, I2PSession.PROTO_ANY, I2PSession.PORT_ANY);
|
||||
|
||||
smtpService = new SMTPService();
|
||||
pop3Service = new POP3Service();
|
||||
relayPacketSender = new RelayPacketSender(sendQueue, relayPacketFolder, appContext);
|
||||
sendQueue = new I2PSendQueue(i2pSession, dispatcher);
|
||||
|
||||
dht = new KademliaDHT(i2pSession.getMyDestination(), sendQueue, dispatcher, configuration.getPeerFile());
|
||||
|
||||
dht.setStorageHandler(EncryptedEmailPacket.class, emailDhtStorageFolder);
|
||||
dht.setStorageHandler(IndexPacket.class, indexPacketDhtStorageFolder);
|
||||
//TODO dht.setStorageHandler(AddressPacket.class, );
|
||||
|
||||
dispatcher.addPacketListener(emailDhtStorageFolder);
|
||||
dispatcher.addPacketListener(indexPacketDhtStorageFolder);
|
||||
|
||||
peerManager = new PeerManager();
|
||||
|
||||
outboxProcessor = new OutboxProcessor(dht, outbox, configuration, peerManager, appContext);
|
||||
|
||||
autoMailCheckTask = new AutoMailCheckTask(configuration.getMailCheckInterval());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes private + public keys for the local destination out to a file.
|
||||
* @param keyFile
|
||||
* @param localDestinationArray
|
||||
* @throws DataFormatException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void saveLocalDestinationKeys(File keyFile, byte[] localDestinationArray) throws DataFormatException, IOException {
|
||||
if (keyFile.exists()) {
|
||||
File oldKeyFile = new File(keyFile.getPath() + "_backup");
|
||||
if (!keyFile.renameTo(oldKeyFile))
|
||||
log.error("Cannot rename destination key file <" + keyFile.getAbsolutePath() + "> to <" + oldKeyFile.getAbsolutePath() + ">");
|
||||
}
|
||||
else
|
||||
if (!keyFile.createNewFile())
|
||||
log.error("Cannot create destination key file: <" + keyFile.getAbsolutePath() + ">");
|
||||
|
||||
FileWriter fileWriter = new FileWriter(keyFile);
|
||||
fileWriter.write(Base64.encode(localDestinationArray));
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
public static void startUp() {
|
||||
getInstance();
|
||||
}
|
||||
|
||||
public static void shutDown() {
|
||||
if (instance != null)
|
||||
instance.stopAllServices();
|
||||
}
|
||||
|
||||
public static I2PBote getInstance() {
|
||||
if (instance == null)
|
||||
instance = new I2PBote();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static String getAppVersion() {
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return Translate.getLanguage(appContext);
|
||||
}
|
||||
|
||||
public Identities getIdentities() {
|
||||
return identities;
|
||||
}
|
||||
|
||||
public AddressBook getAddressBook() {
|
||||
return addressBook;
|
||||
}
|
||||
|
||||
public Destination getLocalDestination() {
|
||||
return i2pSession.getMyDestination();
|
||||
}
|
||||
|
||||
public void sendEmail(Email email) throws Exception {
|
||||
/*XXX*/
|
||||
String recipient = email.getAllRecipients()[0].toString();
|
||||
EmailDestination emailDestination = new EmailDestination(recipient);
|
||||
Collection<UnencryptedEmailPacket> emailPackets = email.createEmailPackets(recipient);
|
||||
Collection<EncryptedEmailPacket> encryptedPackets = EncryptedEmailPacket.encrypt(emailPackets, emailDestination, appContext);
|
||||
for (EncryptedEmailPacket packet: encryptedPackets)
|
||||
dht.store(packet);
|
||||
dht.store(new IndexPacket(encryptedPackets, emailDestination));
|
||||
// TODO uncomment for next milestone, move code above into OutboxProcessor
|
||||
/* outbox.add(email);
|
||||
outboxProcessor.checkForEmail();*/
|
||||
}
|
||||
|
||||
public synchronized void checkForMail() {
|
||||
if (!isCheckingForMail()) {
|
||||
log.debug("Checking mail for " + identities.size() + " Email Identities...");
|
||||
lastMailCheckTime = System.currentTimeMillis();
|
||||
pendingMailCheckTasks = Collections.synchronizedCollection(new ArrayList<Future<Boolean>>());
|
||||
mailCheckExecutor = Executors.newFixedThreadPool(configuration.getMaxConcurIdCheckMail(), mailCheckThreadFactory);
|
||||
for (EmailIdentity identity: identities) {
|
||||
Callable<Boolean> checkMailTask = new CheckEmailTask(identity, dht, peerManager, sendQueue, incompleteEmailFolder, appContext);
|
||||
Future<Boolean> task = mailCheckExecutor.submit(checkMailTask);
|
||||
pendingMailCheckTasks.add(task);
|
||||
}
|
||||
mailCheckExecutor.shutdown(); // finish all tasks, then shut down
|
||||
}
|
||||
else
|
||||
log.debug("Not checking for mail because the last mail check hasn't finished.");
|
||||
}
|
||||
|
||||
public synchronized long getLastMailCheckTime() {
|
||||
return lastMailCheckTime;
|
||||
}
|
||||
|
||||
public synchronized boolean isCheckingForMail() {
|
||||
if (mailCheckExecutor == null)
|
||||
return false;
|
||||
|
||||
return !mailCheckExecutor.isTerminated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the last call to {@link checkForMail} has completed
|
||||
* and added new mail to the inbox.
|
||||
* If this method returns <code>true</code>, subsequent calls will always return
|
||||
* <code>false</code> until {@link checkForMail} is executed again.
|
||||
* @return
|
||||
*/
|
||||
public synchronized boolean newMailReceived() {
|
||||
if (pendingMailCheckTasks == null)
|
||||
return false;
|
||||
if (isCheckingForMail())
|
||||
return false;
|
||||
|
||||
try {
|
||||
for (Future<Boolean> result: pendingMailCheckTasks)
|
||||
if (result.get(1, TimeUnit.MILLISECONDS)) {
|
||||
pendingMailCheckTasks = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while checking whether new mail has arrived.", e);
|
||||
}
|
||||
|
||||
pendingMailCheckTasks = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public EmailFolder getInbox() {
|
||||
return inbox;
|
||||
}
|
||||
|
||||
public int getNumDhtPeers() {
|
||||
if (dht == null)
|
||||
return 0;
|
||||
else
|
||||
return dht.getNumPeers();
|
||||
}
|
||||
|
||||
public DhtPeerStats getDhtStats() {
|
||||
if (dht == null)
|
||||
return null;
|
||||
else
|
||||
return dht.getPeerStats();
|
||||
}
|
||||
|
||||
public Collection<BannedPeer> getBannedPeers() {
|
||||
return BanList.getInstance().getAll();
|
||||
}
|
||||
|
||||
private void startAllServices() {
|
||||
dht.start();
|
||||
// outboxProcessor.start();
|
||||
// relayPacketSender.start();
|
||||
// smtpService.start();
|
||||
// pop3Service.start();
|
||||
sendQueue.start();
|
||||
autoMailCheckTask.start();
|
||||
}
|
||||
|
||||
private void stopAllServices() {
|
||||
if (connectTask != null)
|
||||
connectTask.requestShutdown();
|
||||
if (dht != null) dht.requestShutdown();
|
||||
if (outboxProcessor != null) outboxProcessor.requestShutdown();
|
||||
if (relayPacketSender != null) relayPacketSender.requestShutdown();
|
||||
if (smtpService != null) smtpService.requestShutdown();
|
||||
if (pop3Service != null) pop3Service.requestShutdown();
|
||||
if (sendQueue != null) sendQueue.requestShutdown();
|
||||
if (mailCheckExecutor != null) mailCheckExecutor.shutdown();
|
||||
if (pendingMailCheckTasks != null)
|
||||
for (Future<Boolean> mailCheckTask: pendingMailCheckTasks)
|
||||
mailCheckTask.cancel(false);
|
||||
if (autoMailCheckTask != null) autoMailCheckTask.requestShutdown();
|
||||
|
||||
long deadline = System.currentTimeMillis() + 1000 * 60; // the time at which any background threads that are still running are killed
|
||||
if (dht != null)
|
||||
try {
|
||||
dht.awaitShutdown(deadline - System.currentTimeMillis());
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
log.error("Interrupted while waiting for DHT shutdown.", e);
|
||||
}
|
||||
join(outboxProcessor, deadline);
|
||||
join(relayPacketSender, deadline);
|
||||
join(smtpService, deadline);
|
||||
join(pop3Service, deadline);
|
||||
join(sendQueue, deadline);
|
||||
if (mailCheckExecutor != null) mailCheckExecutor.shutdownNow();
|
||||
join(autoMailCheckTask, deadline);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (mailCheckExecutor!=null && currentTime<deadline)
|
||||
try {
|
||||
mailCheckExecutor.awaitTermination(deadline-currentTime, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("Interrupted while waiting for mailCheckExecutor to exit", e);
|
||||
}
|
||||
try {
|
||||
if (i2pSession != null)
|
||||
i2pSession.destroySession();
|
||||
} catch (I2PSessionException e) {
|
||||
log.error("Can't destroy I2P session.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void join(Thread thread, long until) {
|
||||
if (thread == null)
|
||||
return;
|
||||
long timeout = System.currentTimeMillis() - until;
|
||||
if (timeout > 0)
|
||||
try {
|
||||
thread.join(timeout);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("Interrupted while waiting for thread <" + thread.getName() + "> to exit", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the network, skipping the connect delay.
|
||||
* If the delay time has already passed, calling this method has no effect.
|
||||
*/
|
||||
public void connectNow() {
|
||||
connectTask.startSignal.countDown();
|
||||
}
|
||||
|
||||
public NetworkStatus getNetworkStatus() {
|
||||
if (!connectTask.isDone())
|
||||
return connectTask.getNetworkStatus();
|
||||
else if (dht != null)
|
||||
return dht.isConnected()?NetworkStatus.CONNECTED:NetworkStatus.CONNECTING;
|
||||
else
|
||||
return NetworkStatus.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits <code>STARTUP_DELAY</code> milliseconds or until <code>startSignal</code>
|
||||
* is triggered from outside this class, then sets up an I2P session and everything
|
||||
* that depends on it.
|
||||
*/
|
||||
private class ConnectTask extends I2PBoteThread {
|
||||
volatile NetworkStatus status = NetworkStatus.NOT_STARTED;
|
||||
CountDownLatch startSignal = new CountDownLatch(1);
|
||||
CountDownLatch doneSignal = new CountDownLatch(1);
|
||||
|
||||
protected ConnectTask() {
|
||||
super("ConnectTask");
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
public NetworkStatus getNetworkStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
try {
|
||||
return doneSignal.await(0, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestShutdown() {
|
||||
super.requestShutdown();
|
||||
startSignal.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
status = NetworkStatus.DELAY;
|
||||
try {
|
||||
startSignal.await(STARTUP_DELAY, TimeUnit.MINUTES);
|
||||
status = NetworkStatus.CONNECTING;
|
||||
initializeSession();
|
||||
initializeServices();
|
||||
startAllServices();
|
||||
doneSignal.countDown();
|
||||
} catch (Exception e) {
|
||||
status = NetworkStatus.ERROR;
|
||||
log.error("Can't initialize the application.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
public class Util {
|
||||
private static final int BUFFER_SIZE = 32 * 1024;
|
||||
private static final String BUNDLE_NAME = "i2p.bote.locale.Messages";
|
||||
|
||||
private Util() { }
|
||||
|
||||
public static void copyBytes(InputStream inputStream, OutputStream outputStream) throws IOException {
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int bytesRead = inputStream.read(buffer);
|
||||
outputStream.write(buffer);
|
||||
if (bytesRead < 0)
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeKeyStream(I2PSession i2pSession, OutputStream outputStream) throws DataFormatException, IOException {
|
||||
i2pSession.getMyDestination().writeBytes(outputStream);
|
||||
i2pSession.getDecryptionKey().writeBytes(outputStream);
|
||||
i2pSession.getPrivateKey().writeBytes(outputStream);
|
||||
}
|
||||
|
||||
public static InputStream createKeyStream(I2PSession i2pSession) throws DataFormatException, IOException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
writeKeyStream(i2pSession, outputStream);
|
||||
return new ByteArrayInputStream(outputStream.toByteArray());
|
||||
}
|
||||
|
||||
public static byte[] readInputStream(InputStream inputStream) throws IOException {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[32*1024];
|
||||
while (true) {
|
||||
int bytesToRead = Math.min(inputStream.available(), buffer.length);
|
||||
if (bytesToRead <= 0)
|
||||
break;
|
||||
else {
|
||||
int bytesRead = inputStream.read(buffer, 0, bytesToRead);
|
||||
byteStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
return byteStream.toByteArray();
|
||||
}
|
||||
|
||||
public static ThreadFactory createThreadFactory(final String threadName, final int stackSize) {
|
||||
return new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable runnable) {
|
||||
return new Thread(Thread.currentThread().getThreadGroup(), runnable, threadName, stackSize);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a thread-safe <code>Iterable</code> from a thread-unsafe one.
|
||||
* Modifications to the old <code>Iterable</code> will not affect the
|
||||
* new one.
|
||||
* @param <E>
|
||||
* @param iterable
|
||||
* @return
|
||||
*/
|
||||
public static <E> Iterable<E> synchronizedCopy(Iterable<E> iterable) {
|
||||
synchronized(iterable) {
|
||||
Collection<E> collection = new ArrayList<E>();
|
||||
for (E element: iterable)
|
||||
collection.add(element);
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>i</code>-th element of a <code>Collection</code>'s <code>Iterator</code>.
|
||||
* @param <E>
|
||||
* @param collection
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public static <E> E get(Collection<E> collection, int i) {
|
||||
for (E element: collection) {
|
||||
if (i == 0)
|
||||
return element;
|
||||
i--;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String _(String messageKey) {
|
||||
return Translate.getString(messageKey, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.addressbook;
|
||||
|
||||
import i2p.bote.email.EmailDestination;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Implements the private address book. Holds a set of <code>Addresses</code>.
|
||||
*/
|
||||
public class AddressBook implements Iterable<Contact> {
|
||||
private Log log = new Log(AddressBook.class);
|
||||
private File addressFile;
|
||||
private List<Contact> contacts;
|
||||
|
||||
/**
|
||||
* Reads an <code>AddressBook</code> from a text file. Each contact is defined
|
||||
* by one line that contains an Email Destination and a name, separated by a
|
||||
* tab character.
|
||||
* @param addressFile
|
||||
*/
|
||||
public AddressBook(File addressFile) {
|
||||
this.addressFile = addressFile;
|
||||
contacts = Collections.synchronizedList(new ArrayList<Contact>());
|
||||
|
||||
if (!addressFile.exists()) {
|
||||
log.debug("Address file does not exist: <" + addressFile.getAbsolutePath() + ">");
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Reading address book from <" + addressFile.getAbsolutePath() + ">");
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
input = new BufferedReader(new FileReader(addressFile));
|
||||
|
||||
while (true) {
|
||||
String line = input.readLine();
|
||||
if (line == null) // EOF
|
||||
break;
|
||||
|
||||
String[] fields = line.split("\\t", 2);
|
||||
try {
|
||||
EmailDestination destination = new EmailDestination(fields[0]);
|
||||
String name = null;
|
||||
if (fields.length > 1)
|
||||
name = fields[1];
|
||||
contacts.add(new Contact(destination, name));
|
||||
}
|
||||
catch (DataFormatException e) {
|
||||
log.error("Not a valid Email Destination: <" + fields[0] + ">");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Can't read address book.", e);
|
||||
}
|
||||
finally {
|
||||
if (input != null)
|
||||
try {
|
||||
input.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Error closing input stream.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(addressFile));
|
||||
try {
|
||||
for (Contact contact: contacts) {
|
||||
writer.write(contact.toBase64());
|
||||
writer.write("\t");
|
||||
writer.write(contact.getName());
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Can't save address book to file <" + addressFile.getAbsolutePath() + ">.", e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Contact contact) {
|
||||
contacts.add(contact);
|
||||
}
|
||||
|
||||
public void remove(String destination) {
|
||||
Contact contact = get(destination);
|
||||
if (contact != null)
|
||||
contacts.remove(contact);
|
||||
}
|
||||
|
||||
public Contact get(int i) {
|
||||
return contacts.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up an {@link Contact} by its Base64 key. If none is found,
|
||||
* <code>null</code> is returned.
|
||||
* @param destination
|
||||
* @return
|
||||
*/
|
||||
public Contact get(String destination) {
|
||||
if (destination==null || destination.isEmpty())
|
||||
return null;
|
||||
|
||||
for (Contact contact: contacts)
|
||||
if (destination.equals(contact.toBase64()))
|
||||
return contact;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<Contact> getAll() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return contacts.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Contact> iterator() {
|
||||
return contacts.iterator();
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.email;
|
||||
|
||||
import i2p.bote.UniqueId;
|
||||
import i2p.bote.packet.UnencryptedEmailPacket;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.mail.Header;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetHeaders;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import com.nettgryppa.security.HashCash;
|
||||
|
||||
public class Email extends MimeMessage {
|
||||
private static final int MAX_BYTES_PER_PACKET = 30 * 1024;
|
||||
private static final String[] HEADER_WHITELIST = new String[] {
|
||||
"From", "Sender", "To", "CC", "BCC", "Reply-To", "Subject", "Date", "MIME-Version", "Content-Type",
|
||||
"Content-Transfer-Encoding", "In-Reply-To", "X-HashCash", "X-Priority"
|
||||
};
|
||||
|
||||
private static Log log = new Log(Email.class);
|
||||
private UniqueId messageId;
|
||||
private boolean isNew = true;
|
||||
|
||||
public Email() {
|
||||
super(Session.getDefaultInstance(new Properties()));
|
||||
messageId = new UniqueId();
|
||||
}
|
||||
|
||||
public Email(File file) throws FileNotFoundException, MessagingException {
|
||||
this(new FileInputStream(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Email object from an InputStream containing a MIME email.
|
||||
*
|
||||
* @param inputStream
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private Email(InputStream inputStream) throws MessagingException {
|
||||
super(Session.getDefaultInstance(new Properties()), inputStream);
|
||||
messageId = new UniqueId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Email object from a byte array containing a MIME email.
|
||||
*
|
||||
* @param bytes
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public Email(byte[] bytes) throws MessagingException {
|
||||
super(Session.getDefaultInstance(new Properties()), new ByteArrayInputStream(bytes));
|
||||
messageId = new UniqueId();
|
||||
}
|
||||
|
||||
public void setHashCash(HashCash hashCash) throws MessagingException {
|
||||
setHeader("X-HashCash", hashCash.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all headers that are not on the whitelist, and initializes some
|
||||
* basic header fields.
|
||||
* Called by <code>saveChanges()</code>, see JavaMail JavaDoc.
|
||||
*/
|
||||
@Override
|
||||
public void updateHeaders() {
|
||||
try {
|
||||
super.updateHeaders();
|
||||
scrubHeaders();
|
||||
|
||||
// Set the "Date" field, using english for the locale.
|
||||
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
|
||||
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss +0000", Locale.ENGLISH); // always use UTC for outgoing mail
|
||||
setHeader("Date", formatter.format(calendar.getTime()));
|
||||
} catch (MessagingException e) {
|
||||
log.error("Cannot set mail headers.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the <code>Email</code> with all "BCC" headers removed, except the one for
|
||||
* <code>recipient<code>.
|
||||
* @String recipient
|
||||
* @return
|
||||
* @throws MessagingException
|
||||
* @throws IOException
|
||||
*/
|
||||
private Email removeBCCs(String recipient) throws MessagingException, IOException {
|
||||
// make a copy of the email
|
||||
Email newEmail = new Email();
|
||||
newEmail.setContent(getContent(), getDataHandler().getContentType());
|
||||
|
||||
// set new headers
|
||||
newEmail.headers = new InternetHeaders();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Header> headers = Collections.list(getAllHeaders());
|
||||
for (Header header: headers)
|
||||
if (!"BCC".equals(header.getName()) || !recipient.equals(header.getValue()))
|
||||
newEmail.addHeader(header.getName(), header.getValue());
|
||||
|
||||
return newEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all mail headers except the ones in <code>HEADER_WHITELIST</code>.
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private void scrubHeaders() throws MessagingException {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Header> nonMatchingHeaders = Collections.list(getNonMatchingHeaders(HEADER_WHITELIST));
|
||||
for (Header header: nonMatchingHeaders) {
|
||||
log.debug("Removing all instances of non-whitelisted header <" + header.getName() + ">");
|
||||
removeHeader(header.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param messageIdString Must be a 44-character Base64-encoded string.
|
||||
*/
|
||||
public void setMessageID(String messageIdString) {
|
||||
this.messageId = new UniqueId(messageIdString);
|
||||
}
|
||||
|
||||
public void setMessageID(UniqueId messageId) {
|
||||
this.messageId = messageId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageID() {
|
||||
return messageId.toBase64();
|
||||
}
|
||||
|
||||
public void setNew(boolean isNew) {
|
||||
this.isNew = isNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the email is unread (incoming mail), or
|
||||
* if it has not been sent yet (outgoing mail).
|
||||
* @return
|
||||
*/
|
||||
public boolean isNew() {
|
||||
return isNew;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
try {
|
||||
return getContent().toString();
|
||||
} catch (Exception e) {
|
||||
String errorMsg = "Error reading email content.";
|
||||
log.error(errorMsg, e);
|
||||
return errorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the email into one or more email packets.
|
||||
* If an error occurs, an empty <code>Collection</code> is returned.
|
||||
*
|
||||
* @param bccToKeep All BCC fields in the header section of the email are removed, except this field. If this parameter is <code>null</code>, all BCC fields are written.
|
||||
* @return
|
||||
*/
|
||||
public Collection<UnencryptedEmailPacket> createEmailPackets(String bccToKeep) {
|
||||
ArrayList<UnencryptedEmailPacket> packets = new ArrayList<UnencryptedEmailPacket>();
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
saveChanges();
|
||||
if (bccToKeep == null)
|
||||
writeTo(outputStream);
|
||||
else
|
||||
removeBCCs(bccToKeep).writeTo(outputStream);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Can't write to ByteArrayOutputStream.", e);
|
||||
return packets;
|
||||
} catch (MessagingException e) {
|
||||
log.error("Can't remove BCC headers.", e);
|
||||
return packets;
|
||||
}
|
||||
byte[] emailArray = outputStream.toByteArray();
|
||||
|
||||
// calculate fragment count
|
||||
int numFragments = (emailArray.length+MAX_BYTES_PER_PACKET-1) / MAX_BYTES_PER_PACKET;
|
||||
|
||||
int fragmentIndex = 0;
|
||||
int blockStart = 0; // the array index where the next block of data starts
|
||||
while (true) {
|
||||
int blockSize = Math.min(emailArray.length-blockStart, MAX_BYTES_PER_PACKET);
|
||||
if (blockSize <= 0)
|
||||
break;
|
||||
else {
|
||||
// make a new array with the right length
|
||||
byte[] block = new byte[blockSize];
|
||||
System.arraycopy(emailArray, blockStart, block, 0, blockSize);
|
||||
UniqueId deletionKey = new UniqueId();
|
||||
UnencryptedEmailPacket packet = new UnencryptedEmailPacket(messageId, fragmentIndex, numFragments, block, deletionKey);
|
||||
packets.add(packet);
|
||||
fragmentIndex++;
|
||||
blockStart += blockSize;
|
||||
}
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.email;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.crypto.SHA256Generator;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Uniquely identifies an email recipient. This implementation uses I2P keypairs.
|
||||
*/
|
||||
public class EmailDestination {
|
||||
private Log log = new Log(EmailDestination.class);
|
||||
private PublicKey publicEncryptionKey;
|
||||
private SigningPublicKey publicSigningKey;
|
||||
|
||||
/**
|
||||
* Creates a fresh <code>EmailDestination</code>.
|
||||
*/
|
||||
public EmailDestination() {
|
||||
try {
|
||||
I2PClient i2pClient = I2PClientFactory.createClient();
|
||||
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
|
||||
i2pClient.createDestination(arrayStream);
|
||||
byte[] destinationArray = arrayStream.toByteArray();
|
||||
I2PSession i2pSession = i2pClient.createSession(new ByteArrayInputStream(destinationArray), null);
|
||||
|
||||
initKeys(i2pSession);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Can't generate EmailDestination.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>EmailDestination</code> using data read from a {@link ByteBuffer}.
|
||||
* @param buffer
|
||||
*/
|
||||
public EmailDestination(ByteBuffer buffer) {
|
||||
byte[] encryptionKeyArray = new byte[PublicKey.KEYSIZE_BYTES];
|
||||
buffer.get(encryptionKeyArray);
|
||||
publicEncryptionKey = new PublicKey(encryptionKeyArray);
|
||||
|
||||
byte[] signingKeyArray = new byte[SigningPublicKey.KEYSIZE_BYTES];
|
||||
buffer.get(signingKeyArray);
|
||||
publicSigningKey = new SigningPublicKey(signingKeyArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address A string containing a valid base64-encoded Email Destination
|
||||
* @throws DataFormatException If <code>address</code> doesn't contain a valid Email Destination
|
||||
*/
|
||||
public EmailDestination(String address) throws DataFormatException {
|
||||
String base64Data = extractBase64Dest(address);
|
||||
if (base64Data == null) {
|
||||
String msg = "No Email Destination found in string: <" + address + ">";
|
||||
log.debug(msg);
|
||||
throw new DataFormatException(msg);
|
||||
}
|
||||
|
||||
base64Data += "AAAA"; // add a null certificate
|
||||
Destination i2pDestination = new Destination(base64Data);
|
||||
publicEncryptionKey = i2pDestination.getPublicKey();
|
||||
publicSigningKey = i2pDestination.getSigningPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a Base64-encoded Email Destination in a string. Returns
|
||||
* the 512-byte Base64 string, or <code>null</code> if nothing is found.
|
||||
* Even if the return value is non-<code>null</code>, it is not
|
||||
* guaranteed to be a valid Email Destination.
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
private String extractBase64Dest(String address) {
|
||||
if (address==null || address.length()<512)
|
||||
return null;
|
||||
|
||||
if (address.length() == 512)
|
||||
return address;
|
||||
|
||||
// Check if the string contains 512 chars in angle brackets
|
||||
int bracketIndex = address.indexOf('<');
|
||||
if (bracketIndex>=0 && address.length()>bracketIndex+512)
|
||||
return address.substring(bracketIndex+1, bracketIndex+1+512);
|
||||
|
||||
// Check if the string is of the form EmailDest@foo
|
||||
if (address.indexOf('@') == 512)
|
||||
return address.substring(0, 513);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void initKeys(I2PSession i2pSession) {
|
||||
publicEncryptionKey = i2pSession.getMyDestination().getPublicKey();
|
||||
publicSigningKey = i2pSession.getMyDestination().getSigningPublicKey();
|
||||
}
|
||||
|
||||
public PublicKey getPublicEncryptionKey() {
|
||||
return publicEncryptionKey;
|
||||
}
|
||||
|
||||
public SigningPublicKey getPublicSigningKey() {
|
||||
return publicSigningKey;
|
||||
}
|
||||
|
||||
private byte[] getKeysAsArray() {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
writeTo(byteStream);
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Can't write to ByteArrayOutputStream.", e);
|
||||
}
|
||||
return byteStream.toByteArray();
|
||||
}
|
||||
|
||||
private void writeTo(OutputStream outputStream) throws IOException {
|
||||
try {
|
||||
publicEncryptionKey.writeBytes(outputStream);
|
||||
publicSigningKey.writeBytes(outputStream);
|
||||
}
|
||||
catch (DataFormatException e) {
|
||||
log.error("Invalid encryption key or signing key.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Hash getHash() {
|
||||
// TODO cache the hash value?
|
||||
return SHA256Generator.getInstance().calculateHash(getKeysAsArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two public keys in Base64 representation.
|
||||
*/
|
||||
public String getKey() {
|
||||
return Base64.encode(getKeysAsArray());
|
||||
}
|
||||
|
||||
public String toBase64() {
|
||||
return getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getKey();
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.email;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class EmailIdentity extends EmailDestination {
|
||||
private Log log = new Log(EmailIdentity.class);
|
||||
private PrivateKey privateEncryptionKey;
|
||||
private SigningPrivateKey privateSigningKey;
|
||||
private String publicName;
|
||||
private String description; // optional
|
||||
private String emailAddress; // optional
|
||||
private boolean isDefault;
|
||||
|
||||
/**
|
||||
* Creates a random <code>EmailIdentity</code>.
|
||||
*/
|
||||
public EmailIdentity() {
|
||||
// key initialization happens in the super constructor, which calls initKeys
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>EmailIdentity</code> from a Base64-encoded string. The format is the same as
|
||||
* for Base64-encoded local I2P destinations, except there is no null certificate.
|
||||
* @param key
|
||||
* @throws I2PSessionException
|
||||
*/
|
||||
public EmailIdentity(String key) throws I2PSessionException {
|
||||
key = key.substring(0, 512) + "AAAA" + key.substring(512); // insert a null certificate for I2PClient.createSession()
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.decode(key));
|
||||
|
||||
I2PClient i2pClient = I2PClientFactory.createClient();
|
||||
I2PSession i2pSession = i2pClient.createSession(inputStream, null);
|
||||
initKeys(i2pSession);
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateEncryptionKey() {
|
||||
return privateEncryptionKey;
|
||||
}
|
||||
|
||||
public SigningPrivateKey getPrivateSigningKey() {
|
||||
return privateSigningKey;
|
||||
}
|
||||
|
||||
public void setPublicName(String publicName) {
|
||||
this.publicName = publicName;
|
||||
}
|
||||
|
||||
public String getPublicName() {
|
||||
return publicName;
|
||||
}
|
||||
|
||||
public void setDescription(String name) {
|
||||
this.description = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setDefault(boolean isDefault) {
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
protected void initKeys(I2PSession i2pSession) {
|
||||
super.initKeys(i2pSession);
|
||||
privateEncryptionKey = i2pSession.getDecryptionKey();
|
||||
privateSigningKey = i2pSession.getPrivateKey();
|
||||
}
|
||||
|
||||
private byte[] getKeysAsArray() {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
byteStream.write(getPublicEncryptionKey().getData());
|
||||
byteStream.write(getPublicSigningKey().getData());
|
||||
byteStream.write(getPrivateEncryptionKey().getData());
|
||||
byteStream.write(getPrivateSigningKey().getData());
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Can't write to ByteArrayOutputStream.", e);
|
||||
}
|
||||
return byteStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two key pairs (public + private) as one Base64-encoded string.
|
||||
* @return
|
||||
*/
|
||||
public String getFullKey() {
|
||||
return Base64.encode(getKeysAsArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getKey() + " address=<" + getEmailAddress() + "> identity name=<" + getDescription() + "> visible name=<" + getPublicName() + ">";
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.email;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Represents a set of <code>EmailIdentities</code>.
|
||||
*/
|
||||
public class Identities implements Iterable<EmailIdentity> {
|
||||
private Log log = new Log(Identities.class);
|
||||
private File identitiesFile;
|
||||
private List<EmailIdentity> identities;
|
||||
|
||||
/**
|
||||
* Constructs <code>Identities</code> from a text file. Each identity is defined
|
||||
* by one line that contains two to four tab-separated fields:
|
||||
* Email Destination key, Public Name, Description, and Email Address.
|
||||
* The first two are mandatory, the last two are optional.
|
||||
*
|
||||
* Additionally, the file can set a default Email Destination by including a
|
||||
* line that starts with "Default ", followed by an Email Destination key.
|
||||
* The destination key must match one of the Email Destinations defined in
|
||||
* the file.
|
||||
* @param identitiesFile
|
||||
*/
|
||||
public Identities(File identitiesFile) {
|
||||
this.identitiesFile = identitiesFile;
|
||||
identities = Collections.synchronizedList(new ArrayList<EmailIdentity>());
|
||||
String defaultIdentityString = null;
|
||||
|
||||
if (!identitiesFile.exists()) {
|
||||
log.debug("Identities file does not exist: <" + identitiesFile.getAbsolutePath() + ">");
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Reading identities file: <" + identitiesFile.getAbsolutePath() + ">");
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
input = new BufferedReader(new FileReader(identitiesFile));
|
||||
|
||||
while (true) {
|
||||
String line = input.readLine();
|
||||
if (line == null) // EOF
|
||||
break;
|
||||
|
||||
if (line.toLowerCase().startsWith("default"))
|
||||
defaultIdentityString = line.substring("default ".length());
|
||||
else {
|
||||
EmailIdentity identity = parse(line);
|
||||
if (identity != null)
|
||||
identities.add(identity);
|
||||
}
|
||||
}
|
||||
|
||||
// set the default identity; if none defined, make the first one the default
|
||||
EmailIdentity defaultIdentity = get(defaultIdentityString);
|
||||
if (defaultIdentity != null)
|
||||
defaultIdentity.setDefault(true);
|
||||
else if (!identities.isEmpty())
|
||||
identities.get(0).setDefault(true);
|
||||
} catch (IOException e) {
|
||||
log.error("Can't read identities file.", e);
|
||||
}
|
||||
finally {
|
||||
if (input != null)
|
||||
try {
|
||||
input.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Error closing input stream.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EmailIdentity parse(String emailIdentityString) {
|
||||
String[] fields = emailIdentityString.split("\\t", 4);
|
||||
if (fields.length < 2) {
|
||||
log.debug("Unparseable email identity: <" + emailIdentityString + ">");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
EmailIdentity identity = new EmailIdentity(fields[0]);
|
||||
if (fields.length > 1)
|
||||
identity.setPublicName(fields[1]);
|
||||
if (fields.length > 2)
|
||||
identity.setDescription(fields[2]);
|
||||
if (fields.length > 3)
|
||||
identity.setEmailAddress(fields[3]);
|
||||
return identity;
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
log.debug("Unparseable email identity: <" + emailIdentityString + ">");
|
||||
return null;
|
||||
} catch (I2PSessionException e) {
|
||||
log.debug("Invalid email identity: <" + fields[0] + ">");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the counterpart of the <code>parse</code> method. It encodes a {@link EmailIdentity} into
|
||||
* an entry for the identities file.
|
||||
* @param identity
|
||||
* @return
|
||||
*/
|
||||
private String toFileFormat(EmailIdentity identity) {
|
||||
StringBuilder string = new StringBuilder();
|
||||
string = string.append(identity.getFullKey());
|
||||
string = string.append("\t");
|
||||
string = string.append(identity.getPublicName());
|
||||
string = string.append("\t");
|
||||
if (identity.getDescription() != null)
|
||||
string = string.append(identity.getDescription());
|
||||
string = string.append("\t");
|
||||
if (identity.getEmailAddress() != null)
|
||||
string = string.append(identity.getEmailAddress());
|
||||
return string.toString();
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
String newLine = System.getProperty("line.separator");
|
||||
Writer writer = new BufferedWriter(new FileWriter(identitiesFile));
|
||||
try {
|
||||
EmailIdentity defaultIdentity = getDefault();
|
||||
if (defaultIdentity != null)
|
||||
writer.write("Default " + defaultIdentity.getKey() + newLine);
|
||||
|
||||
for (EmailIdentity identity: identities)
|
||||
writer.write(toFileFormat(identity) + newLine);
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Can't save email identities to file <" + identitiesFile.getAbsolutePath() + ">.", e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(EmailIdentity identity) {
|
||||
if (identities.isEmpty())
|
||||
identity.setDefault(true);
|
||||
identities.add(identity);
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
EmailIdentity identity = get(key);
|
||||
if (identity != null) {
|
||||
identities.remove(identity);
|
||||
|
||||
// if we deleted the default identity, set a new default
|
||||
if (identity.isDefault() && !identities.isEmpty())
|
||||
identities.get(0).setDefault(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default identity. Assumes this <code>Identities</code> already
|
||||
* contains <code>defaultIdentity</code>.
|
||||
* @return
|
||||
*/
|
||||
public void setDefault(EmailIdentity defaultIdentity) {
|
||||
// clear the old default
|
||||
for (EmailIdentity identity: identities)
|
||||
identity.setDefault(false);
|
||||
|
||||
defaultIdentity.setDefault(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default identity, or <code>null</code> if no default is set.
|
||||
* @return
|
||||
*/
|
||||
public EmailIdentity getDefault() {
|
||||
for (EmailIdentity identity: identities)
|
||||
if (identity.isDefault())
|
||||
return identity;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public EmailIdentity get(int i) {
|
||||
return identities.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up an {@link EmailIdentity} by its Base64 key. If none is found,
|
||||
* <code>null</code> is returned.
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public EmailIdentity get(String key) {
|
||||
if (key==null || key.isEmpty())
|
||||
return null;
|
||||
|
||||
for (EmailIdentity identity: identities)
|
||||
if (key.equals(identity.getKey()))
|
||||
return identity;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<EmailIdentity> getAll() {
|
||||
return identities;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return identities.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<EmailIdentity> iterator() {
|
||||
return identities.iterator();
|
||||
}
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.folder;
|
||||
|
||||
import i2p.bote.UniqueId;
|
||||
import i2p.bote.email.Email;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Stores emails in a directory on the file system. Each email is stored in one file.
|
||||
* Filenames are in the format <code><N, O>_<message ID>.mail</code>, where
|
||||
* N is for new (unread or unsent) and O is for old (read or sent).
|
||||
*/
|
||||
public class EmailFolder extends Folder<Email> {
|
||||
protected static final String EMAIL_FILE_EXTENSION = ".mail";
|
||||
|
||||
private Log log = new Log(EmailFolder.class);
|
||||
|
||||
public EmailFolder(File storageDir) {
|
||||
super(storageDir, EMAIL_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an email in the folder. If an email with the same
|
||||
* message ID exists already, nothing happens.
|
||||
* @param email
|
||||
* @throws IOException
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public void add(Email email) throws IOException, MessagingException {
|
||||
// check if an email exists already with that message id
|
||||
if (getEmailFile(email.getMessageID()) != null) {
|
||||
log.debug("Not storing email because there is an existing one with the same message ID: <" + email.getMessageID()+ ">");
|
||||
return;
|
||||
}
|
||||
|
||||
// write out the email file
|
||||
File emailFile = getEmailFile(email);
|
||||
log.info("Mail folder <" + storageDir + ">: storing email file: <" + emailFile.getAbsolutePath() + ">");
|
||||
OutputStream emailOutputStream = null;
|
||||
try {
|
||||
emailOutputStream = new FileOutputStream(emailFile);
|
||||
email.writeTo(emailOutputStream);
|
||||
}
|
||||
finally {
|
||||
if (emailOutputStream != null)
|
||||
try {
|
||||
emailOutputStream.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Can't close file: <" + emailFile + ">", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an <code>Email</code> by message id. If the <code>Email</code> is
|
||||
* not found, <code>null</code> is returned.
|
||||
* The <code>messageId</code> parameter must be a 44-character base64-encoded
|
||||
* {@link UniqueId}.
|
||||
* @param messageId
|
||||
* @return
|
||||
*/
|
||||
public Email getEmail(String messageId) {
|
||||
File file = getEmailFile(messageId);
|
||||
try {
|
||||
return createFolderElement(file);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Can't read email from file: <" + file.getAbsolutePath() + ">", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private File getEmailFile(Email email) {
|
||||
return getEmailFile(email.getMessageID(), email.isNew());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file in the file system for a given message ID, or <code>null</code> if
|
||||
* none exists.
|
||||
* @param messageId
|
||||
* @return
|
||||
*/
|
||||
private File getEmailFile(String messageId) {
|
||||
// try new email
|
||||
File newEmailFile = getEmailFile(messageId, true);
|
||||
if (newEmailFile.exists())
|
||||
return newEmailFile;
|
||||
|
||||
// try old email
|
||||
File oldEmailFile = getEmailFile(messageId, false);
|
||||
if (oldEmailFile.exists())
|
||||
return oldEmailFile;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private File getEmailFile(String messageId, boolean newIndicator) {
|
||||
return new File(storageDir, (newIndicator?'N':'O') + "_" + messageId + EMAIL_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Folder.getNumElements()
|
||||
* @return
|
||||
*/
|
||||
public int getNumNewEmails() {
|
||||
int numNew = 0;
|
||||
for (File file: getFilenames())
|
||||
if (isNew(file))
|
||||
numNew++;
|
||||
|
||||
return numNew;
|
||||
}
|
||||
|
||||
private boolean isNew(File file) {
|
||||
switch (file.getName().charAt(0)) {
|
||||
case 'N':
|
||||
return true;
|
||||
case 'O':
|
||||
return false;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal email filename, doesn't start with N or O: <" + file.getAbsolutePath() + ">");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags an email "new" (if <code>isNew</code> is <code>true</code>) or
|
||||
* "old" (if <code>isNew</code> is <code>false</code>).
|
||||
* @param messageId
|
||||
* @param isNew
|
||||
*/
|
||||
public void setNew(String messageId, boolean isNew) {
|
||||
File file = getEmailFile(messageId);
|
||||
if (file != null) {
|
||||
char newIndicator = isNew?'N':'O'; // the new start character
|
||||
String newFilename = newIndicator + file.getName().substring(1);
|
||||
File newFile = new File(file.getParentFile(), newFilename);
|
||||
boolean success = file.renameTo(newFile);
|
||||
if (!success)
|
||||
log.error("Cannot rename <" + file.getAbsolutePath() + "> to <" + newFile.getAbsolutePath() + ">");
|
||||
}
|
||||
else
|
||||
log.error("No email found for message Id: <" + messageId + ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an email with a given message ID.
|
||||
* @param messageId
|
||||
* @return <code>true</code> if the email was deleted, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean delete(String messageId) {
|
||||
File emailFile = getEmailFile(messageId);
|
||||
if (emailFile != null)
|
||||
return emailFile.delete();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(Email email) {
|
||||
if (!getEmailFile(email).delete())
|
||||
log.error("Cannot delete file: '" + getEmailFile(email) + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Email createFolderElement(File file) throws Exception {
|
||||
Email email = new Email(file);
|
||||
email.setNew(isNew(file));
|
||||
|
||||
String messageIdString = file.getName().substring(2, 46);
|
||||
email.setMessageID(messageIdString);
|
||||
|
||||
return email;
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.folder;
|
||||
|
||||
import i2p.bote.UniqueId;
|
||||
import i2p.bote.network.PacketListener;
|
||||
import i2p.bote.packet.CommunicationPacket;
|
||||
import i2p.bote.packet.EmailPacketDeleteRequest;
|
||||
import i2p.bote.packet.EncryptedEmailPacket;
|
||||
import i2p.bote.packet.dht.DhtStorablePacket;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* A subclass of {@link DhtPacketFolder} that stores email packets and deletes them
|
||||
* upon {@link EmailPacketDeleteRequest}s.
|
||||
*/
|
||||
public class EmailPacketFolder extends DhtPacketFolder<EncryptedEmailPacket> implements PacketListener {
|
||||
private Log log = new Log(EmailPacketFolder.class);
|
||||
|
||||
public EmailPacketFolder(File storageDir) {
|
||||
super(storageDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
|
||||
if (packet instanceof EmailPacketDeleteRequest) {
|
||||
EmailPacketDeleteRequest delRequest = (EmailPacketDeleteRequest)packet;
|
||||
|
||||
Hash dhtKey = delRequest.getDhtKey();
|
||||
DhtStorablePacket storedPacket = retrieve(dhtKey);
|
||||
if (storedPacket instanceof EncryptedEmailPacket) {
|
||||
UniqueId storedDeletionKey = ((EncryptedEmailPacket)storedPacket).getPlaintextDeletionKey();
|
||||
|
||||
if (storedDeletionKey.equals(delRequest.getDeletionKey()))
|
||||
delete(dhtKey);
|
||||
else
|
||||
log.debug("Deletion key in EmailPacketDeleteRequest does not match. Should be: <" + storedDeletionKey + ">, is <" + delRequest.getDeletionKey() +">");
|
||||
}
|
||||
else
|
||||
log.debug("EncryptedEmailPacket expected for DHT key <" + dhtKey + ">, found " + storedPacket.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2009 HungryHobo@mail.i2p
|
||||
*
|
||||
* The GPG fingerprint for HungryHobo@mail.i2p is:
|
||||
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
|
||||
*
|
||||
* This file is part of I2P-Bote.
|
||||
* I2P-Bote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* I2P-Bote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package i2p.bote.folder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <T> The type of objects the folder can store.
|
||||
*/
|
||||
public abstract class Folder<T> implements Iterable<T> {
|
||||
private Log log = new Log(Folder.class);
|
||||
protected File storageDir;
|
||||
protected String fileExtension;
|
||||
|
||||
protected Folder(File storageDir, String fileExtension) {
|
||||
this.storageDir = storageDir;
|
||||
this.fileExtension = fileExtension;
|
||||
|
||||
if (!storageDir.exists() && !storageDir.mkdirs())
|
||||
log.error("Can't create directory: '" + storageDir + "'");
|
||||
}
|
||||
|
||||
public File getStorageDirectory() {
|
||||
return storageDir;
|
||||
}
|
||||
|
||||
public int getNumElements() {
|
||||
return getFilenames().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of all files in the folder.
|
||||
* @return
|
||||
*/
|
||||
public File[] getFilenames() {
|
||||
File[] files = storageDir.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.toUpperCase().endsWith(fileExtension.toUpperCase());
|
||||
}
|
||||
});
|
||||
if (files == null)
|
||||
log.error("Cannot list files in directory <" + storageDir + ">");
|
||||
else
|
||||
// sort files by date, newest first
|
||||
Arrays.sort(files, new Comparator<File>() {
|
||||
@Override
|
||||
public int compare(File f1, File f2) {
|
||||
return (int)Math.signum(f2.lastModified() - f1.lastModified());
|
||||
}
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public Collection<T> getElements() {
|
||||
Collection<T> elements = new ArrayList<T>();
|
||||
Iterator<T> iterator = iterator();
|
||||
while (iterator.hasNext())
|
||||
elements.add(iterator.next());
|
||||
return elements;
|
||||
}
|
||||
|
||||
// An {@link Iterator} implementation that loads one file into memory at a time.
|
||||
@Override
|
||||
public final Iterator<T> iterator() {
|
||||
final File[] files = getFilenames();
|
||||
log.debug(files.length + " files with the extension '" + fileExtension + "' found in '" + storageDir + "'.");
|
||||
|
||||
return new Iterator<T>() {
|
||||
int nextIndex = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return nextIndex < files.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
File file = files[nextIndex];
|
||||
String filePath = file.getAbsolutePath();
|
||||
log.info("Reading file: '" + filePath + "'");
|
||||
try {
|
||||
T nextElement = createFolderElement(file);
|
||||
nextIndex++;
|
||||
return nextElement;
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Can't create a FolderElement from file: " + filePath, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Use the Folder instance to delete a folder element.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract T createFolderElement(File file) throws Exception;
|
||||
}
|