Compare commits

..

973 Commits

Author SHA1 Message Date
d3cb0ab3f6 0.4.1
Checked in late, forgot to do so after actual release
2015-09-28 12:16:31 +00:00
e5fa4706db Fix loading of user guide and FAQ translations (#1641) 2015-09-12 15:40:16 +00:00
ecdd2ee426 Added new user guide translation 2015-09-12 14:30:22 +00:00
784a716f0a Updated translations 2015-09-12 14:29:53 +00:00
afdde691b4 CME fix 2015-09-02 01:33:49 +00:00
65d9439e03 Add owner to new ticket URL 2015-08-23 05:59:08 +00:00
8d19c4c78a Fixed CME 2015-08-21 02:22:35 +00:00
8731a72887 0.4 2015-08-21 02:20:25 +00:00
9e1b42134c Remove build numbers from version 2015-08-21 02:20:02 +00:00
17b4d035eb Update last checked time for manual checks too 2015-08-20 23:58:49 +00:00
d967d50c51 Fix email checking 2015-08-20 23:50:17 +00:00
42770cf01b Updated ignores 2015-08-20 11:53:10 +00:00
c910e17f6c Fix bug with sending anon emails 2015-08-20 11:52:09 +00:00
d408242173 Test OutboxProcessor.sendEmail(), proves existence of bug with anon emails 2015-08-20 11:26:34 +00:00
c52429f393 Add Mockito to unittest deps 2015-08-20 11:24:58 +00:00
aac9df446f 0.3 2015-08-15 23:33:58 +00:00
da40d97185 Temporarily disable IMAP due to class loader issues
Apache Commons Logging can't find the Log4J classes, because (I think) it is
not looking in the plugin's class loader (the classes are visible in I2P-Bote).
2015-08-15 23:23:51 +00:00
e661e4306c Updated ignores 2015-08-15 02:09:45 +00:00
18005cdfb3 Updated translations 2015-08-15 02:01:58 +00:00
1a7e8daf8e Fix app icon so it is bundled 2015-08-15 01:58:23 +00:00
771153c4d7 Add app icon 2015-08-15 01:55:14 +00:00
f1e750cef1 Change author to me (for feedback) 2015-08-15 01:54:54 +00:00
52e30278b5 Bump min I2P version to 0.9.18 (first to include my SU3 plugin cert) 2015-08-15 01:44:51 +00:00
4f1b81510f Add SU3 update URL 2015-08-15 01:32:26 +00:00
0c4d1dc5c3 Changed plugin signer and update URL 2015-08-15 01:28:38 +00:00
c1934b4576 Added missing image 2015-08-15 01:27:32 +00:00
0edd014c6b Deduplicate dependency verification 2015-08-15 01:26:47 +00:00
27e02ce527 Fix connection checking 2015-08-14 01:30:55 +00:00
9aa14a705e Only show "Check email" button for identities when connected 2015-08-14 00:56:50 +00:00
219de6e499 Adjust identities column widths on old themes 2015-08-14 00:56:19 +00:00
d07f790dbb Fix NPE in identity creation by properly saving identity config 2015-08-13 23:35:00 +00:00
8abfc8345b Deduplication 2015-08-13 12:39:37 +00:00
3cbcfaa331 Add config option for including local deps in update
Local deps are now moved out of update, because with the impending change of
plugin signer, all users will have all current JARs.
2015-08-13 12:00:06 +00:00
63b63a9f65 Bugfix 2015-08-13 11:29:42 +00:00
29f5db767d Extract common packing macro, delete .jar files from plugin (JIC) 2015-08-13 11:19:09 +00:00
90545b7046 Add config option for including remote deps in update
Remote deps are now moved out of update, because with the impending change of
plugin signer, all users will have all current JARs.
2015-08-13 11:00:06 +00:00
37b64f25c0 Fix hash verification 2015-08-12 12:10:49 +00:00
5f7bb2d7d1 Verify hashes of remote dependencies 2015-08-08 14:09:58 +00:00
69fc637bd7 Refactor remote dependency checking 2015-08-08 13:50:43 +00:00
cb0b0822a3 Upgrade to JavaMail 1.5.4, make it a remote dependency 2015-08-08 13:47:57 +00:00
f83f7cd085 Updated translations 2015-08-05 13:01:19 +00:00
bab92e082f Upgrade BouncyCastle to 1.52 2015-08-05 12:56:10 +00:00
d1e7eeb7bc Updated translation strings 2015-08-05 01:52:23 +00:00
a5409b0e43 Added new translations 2015-08-05 01:43:08 +00:00
742c697150 Updated translations 2015-08-05 01:42:37 +00:00
42c6269cda Improve recipient handling in email composition 2015-08-05 01:38:21 +00:00
03012e5323 Get IMAP STARTTLS working 2015-08-04 16:23:58 +00:00
97825a3d60 Upgrade to 20150627 snapshot of Apache James 2015-08-04 16:18:29 +00:00
dc5d066775 Get tests to pass 2015-08-03 13:21:57 +00:00
c2bc331b55 Add Email Date header tests 2015-08-03 13:19:17 +00:00
8f29c7d6fb Force loading of BouncyCastly so tests pass 2015-08-03 13:18:49 +00:00
6b530a364b Add direct link to creating tickets for I2P-Bote 2015-07-31 04:01:41 +00:00
3f60643c2e Updated history 2015-07-23 09:34:49 +00:00
3539b5a13b Don't move metadata file if we couldn't move email file (#1196) 2015-07-23 02:37:25 +00:00
e37f70506d Don't assume that email metadata file exists (#1196) 2015-07-23 02:27:09 +00:00
4196486799 Fix NPE (#937) 2015-07-22 21:16:18 +00:00
6dbecc0f6e Unused import 2015-07-22 12:30:51 +00:00
d209c9f94b Delete malformed packets from disk (#1287)
Incomplete email packets are unaffected because IncompleteEmailFolder overrides
the default behavior.
2015-07-22 11:44:49 +00:00
6e528dae6a Fix CME caused by no synchronization on kBuckets (#1586) 2015-07-21 10:09:32 +00:00
90f9de4861 Updated guide translations 2015-07-21 09:01:58 +00:00
f7b3499e93 Updated translations 2015-07-21 08:47:31 +00:00
5901565d74 Listen to identity updates too 2015-06-05 10:08:39 +00:00
f98990ad65 Added IdentitiesListener 2015-06-05 09:37:10 +00:00
d290665a17 New user guide translation for es 2015-03-20 09:31:16 +00:00
e2e2233b89 User guide fixes (thx strel!) 2015-03-20 09:25:31 +00:00
29190552d9 Updated translations 2015-03-20 09:24:29 +00:00
371ae89bc3 Preparation for moving StrongTls to i2p.jar:
- Removed last of pre-existing code
- Moved to net.i2p.util package
- Relicensed to public domain
- Improved interface
2015-03-19 19:49:55 +00:00
a34da62789 Overhauled StrongTls with 2015-era protocols and ciphers 2015-03-19 00:51:35 +00:00
8ff2c84cd4 Discovered that one of the old bootstrapping nodes is kytv, now resurrected 2015-03-16 10:12:19 +00:00
96140a49c5 New bootstrap peers (thanks str4d and The_Tin_Hat!) 2015-03-16 06:06:18 +00:00
b3f9ea8a0b Updated TODO 2015-03-12 21:45:10 +00:00
034660d4af Updated translations 2015-03-10 11:28:10 +00:00
bbda61316e Formatting changes by Transifex, and some string fixes 2015-03-10 11:22:45 +00:00
297a26cc63 Added user guide and FAQ to Transifex config 2015-03-10 11:22:26 +00:00
c9686adaef More formatting fixes for Transifex 2015-03-10 10:57:59 +00:00
82d31e4813 Formatting fixes for Transifex 2015-03-10 10:49:55 +00:00
63c17045b6 Multi-line Spanish translation 2015-03-10 10:40:06 +00:00
0566e42f21 New translation of FAQ into Spanish (thanks trolly!) 2015-03-10 04:16:22 +00:00
a21f67d429 Fixes 2015-02-15 10:52:36 +00:00
d7ae6d51e5 FAQ navigation 2015-02-15 10:23:13 +00:00
271eb004b2 Android themed wait.gif 2015-02-15 09:21:46 +00:00
c65e3f8f7e UI option for global identity check 2015-02-15 09:21:30 +00:00
dd7f4055a1 Prevent potential NPE 2015-02-15 09:20:52 +00:00
9b0836249d Bugfix 2015-02-15 07:13:17 +00:00
0585f211fb Implement checking individual identities 2015-02-15 03:25:40 +00:00
4df989d63a Don't disable default selection for new identities when only one exists 2015-02-14 22:33:59 +00:00
a76789cf30 Button layout fix 2015-02-14 22:33:34 +00:00
ae55336e06 Updated translations 2015-02-14 22:32:50 +00:00
437c5ddbac Backend implementation of per-identity relay settings, global check exclusion 2015-02-14 21:51:01 +00:00
63a574f578 Show which nav item is currently selected 2015-02-13 02:21:53 +00:00
42c3e0d369 Match nav drawer list item highlight to Material design spec 2015-02-13 02:01:13 +00:00
5d89032b90 Corrections from Material design spec 2015-02-13 01:55:57 +00:00
fc738142fa Moved getBooleanParameter() and getIntParameter() to Util 2015-02-07 19:51:39 +00:00
4e9b0e93cb Extract String constants 2015-02-06 10:00:05 +00:00
8912cfcf7d Include HTML files in WAR 2015-02-05 10:33:06 +00:00
73e22a3d34 Reference ticket numbers in TODO 2015-02-05 09:36:42 +00:00
dfa1dfbd74 Settings headings 2015-02-04 11:21:27 +00:00
eff95792ac Updated translations 2015-02-04 11:00:52 +00:00
bf53778367 String fix 2015-02-04 11:00:29 +00:00
74bde7aac6 HTML5 cleanups 2015-02-04 01:14:44 +00:00
848ec8cb14 Added not-yet-implemented features to TODO 2015-02-04 00:56:29 +00:00
a72bd3fb04 FAQ formatting 2015-02-03 14:22:22 +00:00
87ce7646f6 FAQ pagetitle 2015-02-03 14:19:29 +00:00
e2c003503a Reformatted FAQ 2015-02-03 14:16:46 +00:00
4f9d717725 List tweaks 2015-02-03 12:58:16 +00:00
f638d8e43a Limit user guide navigation width 2015-02-03 12:30:11 +00:00
2377acf15c Reorganized user guide sections 2015-02-03 12:29:19 +00:00
f11af022b2 User guide navigation 2015-02-03 12:25:31 +00:00
9ef5a15650 Removed unnecessary installation details, renumbered headings 2015-02-03 11:59:50 +00:00
02bb52dc67 Title fixes 2015-02-03 11:51:41 +00:00
bd9a0bd6b4 Consolidated credits 2015-02-03 11:32:04 +00:00
fe7516c24f Reworked user guide intro 2015-02-03 08:43:54 +00:00
97c567a105 User guide fixes 2015-02-03 04:55:16 +00:00
62308d053d Translation string fixes 2015-02-03 04:55:02 +00:00
f4ebc330a1 Translation fixes 2015-02-03 04:54:42 +00:00
93cabe4f44 Updated translation strings 2015-02-03 04:28:37 +00:00
5222861962 Proper theme names 2015-02-03 04:15:55 +00:00
9c09c739d2 Fixed bundle-messages.sh 2015-02-03 04:15:46 +00:00
8b3770f33d New translations 2015-02-03 03:52:46 +00:00
cd5d8b0ac2 Updated translations 2015-02-03 03:52:32 +00:00
596aa39d5d Updated Transifex config 2015-02-03 03:52:25 +00:00
212ca673b0 Updated TODO 2015-02-03 03:41:01 +00:00
9833590266 Move HTML files to subdir in preparation for Transifex 2015-02-03 03:40:50 +00:00
77242920bd Updated French translation of user guide 2015-02-03 03:33:22 +00:00
19a8c09a8d User guide tweaks 2015-02-03 03:33:00 +00:00
2634398ea4 Renamed user guide HTML 2015-02-02 22:41:19 +00:00
2fac3e9eae Tidied up user guide HTML 2015-02-02 22:40:04 +00:00
182bafb524 Enable HTML files to be themed 2015-02-02 22:32:52 +00:00
d7c673e4be Charts on network status page 2015-02-02 03:17:28 +00:00
33273675da Mark new relay peers instead of showing 0% reachability 2015-02-01 04:43:45 +00:00
7b405764fb NPE fix (ticket #1367) 2015-01-30 06:03:01 +00:00
750305fef1 Attachments icon 2015-01-30 05:38:57 +00:00
269f0d07e9 Improved info and error message displaying 2015-01-29 05:03:26 +00:00
7aae76ef4b Fixes after XSSFilter 2015-01-29 04:39:03 +00:00
302414a53d Enable different page title from browser title, more sidenav icons 2015-01-29 04:38:21 +00:00
22732d33c1 Missing bcprov changes 2015-01-28 23:54:55 +00:00
b113dd3e51 Font changes 2015-01-28 08:04:53 +00:00
ca0ac05614 Import identities 2015-01-28 06:47:47 +00:00
54ac8425b5 Export identities 2015-01-28 04:33:03 +00:00
67e36d834e Escape XML 2015-01-28 04:25:51 +00:00
48c2294517 HTML5 <time> 2015-01-27 02:48:12 +00:00
e3e694d0c9 Enable XSSFilter on all inputs except passwords 2015-01-27 01:43:12 +00:00
06fc60af43 Material tweak for new emails 2015-01-27 01:41:33 +00:00
9cd8bddf8a Bugfix 2015-01-27 01:30:29 +00:00
6c4ab4b1b3 NPE fix when attempting to change identity name to blank 2015-01-27 01:14:33 +00:00
3155308054 New theme based on the Material design of the Bote Android app 2015-01-26 10:32:42 +00:00
538a5b2e06 Change addressbook.gif to addressbook.png 2015-01-26 10:02:05 +00:00
dd126df6c7 Inputs to buttons 2015-01-26 07:41:43 +00:00
a1edb3173c Remove onclick from header, the inbox is easily accessed from the side nav 2015-01-26 04:56:34 +00:00
edc51acedb An article around email content 2015-01-26 04:24:07 +00:00
0394b591a7 Extra page title for use in new theme 2015-01-26 03:45:03 +00:00
9a5a161342 CSS tweak 2015-01-25 10:19:05 +00:00
ec3acae530 Replaced linebreak with margin 2015-01-25 09:32:05 +00:00
7fea66978b Remove "Public Address Directory" from side nav until it has a link 2015-01-25 09:21:16 +00:00
b7abb03b32 HTML5, preparations for new theme 2015-01-25 09:18:40 +00:00
958a072d9b HTML5 doctype and charset 2015-01-24 12:31:42 +00:00
e7042dc5a7 Detect file MIME types 2015-01-12 07:55:51 +00:00
bc6df473be Ask for plugin SU3 keystore password 2015-01-12 07:34:17 +00:00
04ac90d478 Prevent NPE on Android if the state gets weird (it has happened) 2015-01-11 12:25:45 +00:00
7e8421c63b Added ignores 2015-01-11 05:51:22 +00:00
3591d25f72 Migrate i2p.bote.crypto AES and EC to JCA; upgrade to BouncyCastle 1.51
This change was necessary to fix the crypto on Android, where SpongyCastly must
be used instead (because of classloader conflicts). The new ECUtils class
contains the remaining code that could not be made provider-agnostic. In
particular, the EmailDestination format for EC requires the use of BouncyCastle
point encoding.

The full BouncyCastle library is now bundled, because it must be added as a
Security Provider to use the JCA system, and this requires a valid signature.

JCA is used for AES operations instead of I2P's built-in AES engine because the
PKCS#7 padding class could not be accessed on its own in a provider-agnostic
manner. The resulting code is also cleaner.
2015-01-04 22:16:16 +00:00
1f1b328f70 Close InputStream in Util.getPartSize() 2015-01-04 05:00:08 +00:00
823491ae4d Pull out Util method for getting size of a Part 2014-12-28 11:42:23 +00:00
6856773636 Correct the Attachment interface 2014-12-28 11:42:02 +00:00
2cc3df7c1f Generalize attachments 2014-12-28 04:52:27 +00:00
852bad8d61 Moved JSPs to correct location
For i2pbote.war the location doesn't matter, because the JSPs are compiled. For
the Eclipse testnet, the JSPs are not compiled and cannot be located because
access to files in WEB-INF is restricted.
2014-12-23 10:47:11 +00:00
4f357db8ec Use I2PSocketManagerFactory.createDisconnectedManager() for better connectError 2014-12-17 23:54:31 +00:00
877b02cc04 Layout fix 2014-12-13 10:56:30 +00:00
8b5b7507c6 Helpers to get the name for an EmailDestination 2014-11-18 04:00:00 +00:00
5ff770bc31 Use assertArrayEquals 2014-11-17 22:39:04 +00:00
4107467c64 Mockery thread synchronization 2014-11-17 22:23:20 +00:00
05def741fb Fix BCC header removal bug 2014-11-17 21:41:57 +00:00
82ac0d59d8 Unused imports 2014-11-17 21:25:00 +00:00
10445e1082 junit.framework -> org.junit 2014-11-17 21:15:00 +00:00
a968f5c6f4 Updated history 2014-09-25 05:54:49 +00:00
d6564680a5 Update to techdoc by HungryHobo 2014-09-25 05:54:31 +00:00
ec41d7d82e Switch to Maven directory structure without losing history 2014-09-25 05:50:39 +00:00
8a29b9dd0d Mark locations of code incompatible with newer I2P Destinations 2014-09-21 05:32:43 +00:00
6c53344f51 A zero-length password is an uncached password
This brings PasswordCache in line with FileEncryptionUtil.
2014-09-21 05:31:08 +00:00
2768297be9 Add and remove interface for password listeners 2014-09-18 06:11:01 +00:00
740197e439 Added TODO 2014-08-26 11:55:12 +00:00
6e4c52b746 Remove spaces and newlines 2014-08-07 11:56:43 +00:00
cc59ed9adb Remove possible prefixes 2014-08-07 11:46:58 +00:00
3c0a431f09 Remove UpdateChecker
Plugins have been auto-updated by the router for a while now
2014-08-03 10:47:11 +00:00
392ba71037 Another Tomcat 7 fix, see rev. 5e9c9148 2014-08-03 10:42:32 +00:00
e39abcc145 Use SecureFile instead of Util.makePrivate()
* Replace Util.makePrivate() with SecureFile and SecureFileOutputStream
* Make derivparams a SecureFile
2014-08-02 16:46:17 +00:00
e030e9ed5f 0.2.10 2014-07-23 21:36:12 +00:00
1896fccf1f Fix NullPointerExceptions 2014-07-23 21:25:31 +00:00
ca19e9d9e0 Use a separate SessionKeyManager instead of the router's 2014-07-23 21:24:39 +00:00
729a4ac99f Upgrade to 20140722 snapshot of Apache James 2014-07-23 21:22:15 +00:00
729f59e729 Support I2CP connections over Unix domain sockets
Only supported on Android for now.
2014-07-16 04:05:35 +00:00
78b66b5509 Bugfix after net.i2p.data.Base64.decode() errors were cleaned up 2014-07-07 00:28:22 +00:00
5cdcae1416 Missing network status change 2014-07-06 14:26:47 +00:00
348262e7a2 NetworkStatusListener implementation 2014-07-06 13:05:39 +00:00
adb290658a Inform caller if importer found no identities 2014-07-06 02:55:44 +00:00
c04fc24445 Implement encrypted identities export 2014-07-06 02:28:40 +00:00
4762f8486e Implement identity appending on import 2014-07-05 23:50:02 +00:00
52a717d7e3 Import identities from FileDescriptor (no appending possible yet) 2014-07-05 04:23:19 +00:00
e9ffb4643b Export identities to file (no encryption possible yet) 2014-07-04 06:21:17 +00:00
382f75f4a4 Pulled out Identities <-> Properties conversion into separate methods 2014-07-04 00:23:14 +00:00
4a6fc262e7 Show number of incomplete emails 2014-07-02 09:23:58 +00:00
4cd24cd579 Expose number of incomplete emails 2014-07-02 06:38:02 +00:00
32ce92d7cb Updated license.txt 2014-06-23 01:47:07 +00:00
96bb3a0719 Enable saving picture for EmailIdentity 2014-06-16 05:41:11 +00:00
5cebc0b2ee Added EmailIdentity.setPictureBase64() 2014-06-16 04:57:32 +00:00
4e7d57d8e3 Implement vanity destinations 2014-06-11 21:11:11 +00:00
0ad03ce6d4 Fix for new Jetty/Tomcat 2014-06-11 06:13:13 +00:00
2082fd0856 Emails are not kept in-memory inside EmailFolder, so store \Recent in metadata 2014-06-10 12:17:35 +00:00
98c56de3a5 Added specific listener for newly-received emails 2014-06-09 04:51:20 +00:00
1801e308b2 Fixed bug in setFlags() 2014-06-08 06:46:56 +00:00
f318587209 Helper method 2014-06-08 04:59:13 +00:00
38d5833551 Improved FolderListener, emails added to a folder outside IMAP now get \Recent 2014-06-08 04:12:30 +00:00
6bbd015d38 Store other IMAP flags in-memory (like \Recent) 2014-06-08 02:59:39 +00:00
f20ae940a8 Add missing file 2014-06-03 06:01:55 +00:00
f7f185a68c Handle index packets that are bigger than a datagram (fixes "After merging, IndexPacket is too big..." errors) 2014-06-02 21:01:26 +00:00
a47100d14a Fix NullPointerException on fresh installs 2014-05-29 22:21:09 +00:00
32bd6e45a8 Fixes for Tomcat 7 which is more anal about the JSP spec than Jetty or Tomcat 6 2014-05-29 22:14:28 +00:00
ca19b0929e NPE fix for corrupt folder 2014-05-24 00:00:34 +00:00
3dede23a24 Reworked email status storage for UI flexibility 2014-05-23 01:18:18 +00:00
e190587330 Reverted bad log tweak 2014-05-17 04:37:23 +00:00
0d92ddb6e1 Set connectTask to null so getNetworkStatus() returns valid state 2014-05-17 04:36:42 +00:00
52f6405c74 Removed unused import 2014-05-17 04:33:28 +00:00
99fb8bf264 NPE fixes, log tweak 2014-05-17 04:27:59 +00:00
fa22d47252 Whitespace, don't create SSL key store on Android 2014-05-17 04:21:06 +00:00
2dfa656b06 JSSE requires keystore and key passwords to be identical 2014-05-13 05:07:05 +00:00
56aa3f3c1c Generate the SSL cert on-the-fly to prevent MITM 2014-05-13 02:23:09 +00:00
c2e75290fb Reverted mistaken checkin 2014-05-13 02:20:19 +00:00
3387cdd90c Enable STARTTLS for IMAP and SMTP using selfsigned certificate
Certificate domain is 127.0.0.1, clients will throw a warning if using localhost
(alongside the warning for selfsigned cert).
2014-05-12 13:49:13 +00:00
c3088c5931 Mark important comments 2014-05-12 13:23:28 +00:00
a149a0bdc0 Fixed NPE (ticket #1272) 2014-05-12 12:37:47 +00:00
7867198fe9 Override updateMessageID() on Android to prevent NetworkOnMainThreadException 2014-04-17 23:27:40 +00:00
38293ebcf9 Added elementUpdated() to FolderListener, made setNew() throws consistent 2014-04-16 13:07:17 +00:00
6f4a0615ff Update FolderListeners when Email is moved 2014-04-15 00:58:02 +00:00
22fa6105ac Updated FAQ and User's Guide 2014-04-14 02:30:00 +00:00
946fa8d6ec Insert addressbook/identity names, @bote, {UNK} into IMAP email headers 2014-04-14 02:29:37 +00:00
5a8d9c6f4f Remove @bote before validating sender and recipient addresses in SMTP 2014-04-13 05:05:41 +00:00
5c53c2071b Updated about.jsp 2014-04-13 02:45:57 +00:00
c84770036d Create BoteMailboxes once, and remove their FolderListeners when IMAP stops 2014-04-13 02:27:31 +00:00
d9756407b0 Refactor to handle recipient headers containing multiple recipients 2014-04-13 01:46:13 +00:00
fe9c6d9d47 Pack new mailapi.jar in update for 0.2.10 2014-04-11 22:42:07 +00:00
ee96addef6 Removed signature from scrypt jar (pack200 interferes) 2014-04-10 21:51:49 +00:00
1f9aa61d2f Upgraded to scrypt 1.4.0 2014-04-10 20:59:44 +00:00
zzz
5e559846db one more typo 2014-04-07 13:26:10 +00:00
bbd24eaaff fix another missing '/' 2014-04-07 12:20:12 +00:00
4db680f067 add missing / to paths 2014-04-07 12:14:44 +00:00
79595913f2 Previous fix wasn't quite right 2014-04-04 20:01:29 +00:00
b387b77bfb Fixed concurrency problem 2014-03-30 03:10:04 +00:00
dce43d11ae Fixed IMAP UID implementation to conform to RFC 3501 2014-03-30 02:14:56 +00:00
8fec6b28e8 Remove @bote properly from SMTP messages 2014-03-29 03:19:53 +00:00
17282cda4d Missing Bean method 2014-03-28 20:58:26 +00:00
1664253417 Fixed password "corruption" (ticket #1239) 2014-03-28 20:57:56 +00:00
654b136cb0 Somehow, file duplication has stopped 2014-03-18 20:04:50 +00:00
2b5de7958e Doc tweak 2014-03-18 10:56:28 +00:00
10b9b2e593 Updated identity file spec 2014-03-18 10:22:47 +00:00
3571adf2ec Another StatusListener 2014-03-09 23:05:22 +00:00
44027e80ca Save and load default key properly 2014-03-09 09:11:00 +00:00
9d821f66b9 Update default identity when changed (for writing to file) 2014-03-08 23:07:54 +00:00
bef847d270 Moved Servlet-dependent helper methods back to JSPHelper 2014-03-04 01:46:56 +00:00
967a523130 Missing javadoc @param 2014-03-04 01:36:11 +00:00
c35e9c9139 Enable listening to status of internal operations (for Android UI) 2014-03-02 10:32:23 +00:00
c0b62e25c1 Remove throw (handled in rev 78f6a5bcf158019aceb75a48aebd8d9c20b203ce) 2014-03-01 01:55:15 +00:00
936e1e7d50 Updated techdoc.txt for mailapi.jar 2014-02-28 22:08:34 +00:00
592793eaac Add a setting to enable/disable SMTP 2014-02-28 22:02:49 +00:00
f1c9ac9788 Updated to mailapi 1.5.1 2014-02-27 05:19:54 +00:00
bdd24d7e9d Apparently Jasper can't follow inheritance 2014-02-27 04:40:15 +00:00
de36d91909 Delete i2pbote.jar in clean 2014-02-27 03:28:18 +00:00
1a6ae22b99 Allow using result of folder.getName() in getMailFolder()
This is used for saving instance state in Android.
2014-02-27 03:00:03 +00:00
adde9736be Split JSPHelper so common utilities can be used by other UIs (Android) 2014-02-26 23:08:34 +00:00
173d08d798 Allow FolderListeners to be removed 2014-02-26 07:07:42 +00:00
acb1ace33a Don't add source files to i2pbote.jar (it duplicates .txt files) 2014-02-26 07:07:11 +00:00
ffa7450e77 Reordered list of folders 2014-02-26 03:28:18 +00:00
d9d9c47124 Add README.md for GitHub 2014-02-16 18:18:45 +00:00
d960308461 Update techdoc.txt 2014-02-16 13:41:27 +00:00
616df8de9f Update translations from Transifex 2014-02-16 13:40:34 +00:00
427e293bac 0.2.9 2014-02-16 13:39:32 +00:00
163f8d58c0 Make send button easier to find 2014-01-08 01:44:02 +00:00
43e34eb221 Added code to mapper for fetching recent messages
This functionally changes nothing, because BoteMessage.isRecent()
always returns false.
2014-01-01 21:30:02 +00:00
c2d1334c04 Unset flags correctly 2014-01-01 05:57:41 +00:00
a05890eaec Implemented deleting via IMAP
The \Deleted flag is stored in EmailMetadata, but is ignored by Bote and only
used for IMAP deletion.
2013-12-31 20:20:17 +00:00
2a744fb1cd RFC 2822: set From: header 2013-12-31 16:43:55 +00:00
ed60728edd Don't delete libs with "ant clean" 2013-12-31 07:29:26 +00:00
48e69d3cd5 Don't break folder list if an email can't be decrypted 2013-12-27 02:33:26 +00:00
df09332ead Added libs to .jar manifest (so IMAP setting works) 2013-12-26 09:54:01 +00:00
585413fa2b Fixed potential NPE 2013-12-25 23:30:02 +00:00
68c48cb332 Update to jMock 2.6.0 (v2.5.1 is not available from their website anymore) 2013-05-01 18:12:55 +00:00
ae87a801ea Fix classpath and typos 2013-05-01 17:52:44 +00:00
901b051546 Implement SMTP 2013-05-01 17:50:42 +00:00
6590e3122a Shorten known email destinations in the folder view 2013-04-29 19:18:02 +00:00
e601b5f46e Add a setting to enable/disable IMAP 2013-04-29 18:53:41 +00:00
641085ab24 don't try to zip up non-existent images directory (see rev. 1ae37d314f064cfb6c870727775f5b5ccc5ea69e) 2013-04-29 18:34:15 +00:00
5d371f983a IMAP interface, works with Thunderbird but not Evolution 2013-04-29 00:21:37 +00:00
8fc111fc86 Fix Content-Transfer-Encoding (8bit doesn't allow zeros, CR, or LF) 2013-04-26 23:15:13 +00:00
2dc809c025 Close streams when done reading 2013-04-26 23:06:15 +00:00
7b0149dc39 by request, adding my i2pbote node's public destination 2013-04-11 16:00:55 +00:00
24509df2b5 Delete commented out line 2013-04-02 21:47:28 +00:00
263b68550e Fix a compiler warning 2013-04-02 21:42:34 +00:00
ae3ac8b5be Attach file on selection when JS is enabled 2013-04-02 21:33:36 +00:00
7c22899f32 try supressing/fixing a few warnings 2013-04-01 21:01:18 +00:00
3970d6d015 build fix (don't try to zip up non-existent images directory) 2013-04-01 20:40:12 +00:00
4464301119 Remove unused images 2013-04-01 18:08:37 +00:00
f0622d202b Move style attributes to CSS 2013-04-01 17:57:59 +00:00
63e260f932 Show anonymous sender in italics 2013-03-31 22:36:24 +00:00
87ad8db92a Display of signatures:
* Combine signature column and replied column
 * Don't show signature warning for anonymous emails
2013-03-31 22:23:00 +00:00
cc7e0209ec Simplification 2013-03-30 23:01:32 +00:00
1a4c25a32f Add a null check 2013-03-30 22:58:14 +00:00
79339a0208 Fix a comment 2013-03-30 22:57:26 +00:00
249389a4d3 Replace ReentrantLock with synchronized 2013-03-30 08:55:16 +00:00
92a5a998d6 Show a wait page when the password is changed 2013-03-29 17:09:10 +00:00
e1a49cf440 Add a JSP that allows users to check encrypted files 2013-03-24 12:32:31 +00:00
e30cb79c5f 0.2.8 2013-03-08 21:51:26 +00:00
49268b21ea Increase #words to 8 and #zero bits to 10 2013-03-07 21:38:57 +00:00
74384e0517 Fix: unneccessary lookup when confirm=true 2013-03-07 21:25:44 +00:00
9bfde0ac33 Fix formatting on editIdentity.jsp 2013-03-07 21:22:36 +00:00
55d5ea6084 Fix NullPointerException when no word list is available for the current language 2013-03-05 23:01:49 +00:00
0e36c3dcc3 Fix: Escape characters handled incorrectly when saving and loading 2013-03-05 22:40:08 +00:00
0155e5f57f Implement mark() and reset() 2013-03-05 22:14:02 +00:00
a2b3833602 Store fingerprint with email identity and show it on editIdentity.jsp 2013-03-05 19:29:43 +00:00
200d9ceb3d Switch address book to a properties-style format; show imported picture and text on editContact.jsp 2013-03-03 12:48:36 +00:00
69fd2431c8 Switch identities file to a properties-style format; show published picture and text on editIdentity.jsp 2013-02-26 21:48:06 +00:00
66020b2fc7 Add 0.2.7 release notes 2013-02-14 15:35:32 +00:00
34e76ce627 Add a missing test 2013-02-12 13:30:15 +00:00
79393f0ea8 Fix ContactTest when run from Ant 2013-02-12 13:29:41 +00:00
c4cdbb98cc trim() name before publishing or doing a lookup 2013-02-11 21:24:28 +00:00
eda69d1e7e Fix @bote.i2p suffix 2013-02-11 21:23:00 +00:00
1f2c528b9b Sign Contact packets:
* sign on publish
 * verify on import
 * ignore invalid Contact packets in lookups
2013-02-11 21:18:01 +00:00
6a99b034b7 Implement fingerprints for directory entries 2013-02-11 12:03:15 +00:00
17db81eee1 Use native scrypt if available 2013-02-04 22:13:33 +00:00
d50c843145 Change DEFAULT_PASSWORD_CACHE_DURATION back to 10 (I accidentally changed it to 1 in rev f957174cc94b1ed2a836e94cb71850ed612f2622) 2013-02-04 21:51:02 +00:00
7cbf364407 Rename DirectoryEntryTest to ContactTest 2013-02-04 21:47:57 +00:00
bd8674950e Add null check 2013-02-02 12:18:11 +00:00
0a0418f83f Make sure test files and directories are cleaned up 2013-02-02 12:17:11 +00:00
a5832cd1e4 Add comment 2013-02-02 12:15:29 +00:00
ccbc2c3e01 Check for existing name before publishing 2013-02-02 12:09:26 +00:00
d5c6c2d046 Ignore requests to replace existing Contacts 2013-02-02 00:04:12 +00:00
d8a606946e Don't skip sleep() on exceptions; lower log level 2013-01-27 22:30:58 +00:00
dbaa00d5b1 Print number of running threads 2013-01-27 22:30:17 +00:00
844bfcb842 Implement basic address directory 2013-01-27 22:29:01 +00:00
882a6d207a merge of '8d66ebeab68f6165dbd977cb2b5a5d52d09eab03'
and 'd27fa448d59dd46241e032896b0788e9057da5e1'
2013-01-27 21:59:38 +00:00
730aff2a50 Updated Norwegian Bokmål translation updates from transifex.
(100% translation)
2013-01-26 19:17:27 +00:00
de6d2d60a9 Lower max packet size to 10 kBytes 2013-01-24 20:57:57 +00:00
a724a521cd Add an option to change the ping interval 2013-01-24 20:39:49 +00:00
eaaf3c90e4 Remove Util.get(Collection, int) and use toArray() instead 2013-01-24 20:37:39 +00:00
a0febacdfd Fix: addresses and identities still available after password cache expires 2013-01-23 21:42:24 +00:00
2f0cb066ab Fix forward URL when context path is something other than /i2pbote 2013-01-23 21:08:46 +00:00
fc89896246 Don't attempt to show number of new emails when a password needs to be entered first (metadata is password protected as of recently) 2013-01-22 22:05:27 +00:00
e9c262c8b7 Add package.html files 2013-01-22 20:49:32 +00:00
093e439e04 Fix JavaDoc warnings 2013-01-22 20:31:17 +00:00
bf07f9c664 merge of '90e5bcb2bddcd45813c9eb3b354026f37152c66e'
and 'a6a21a22bbe0d4a61750abff96d5aaaa23b8df54'
2013-01-21 22:27:35 +00:00
bba9ac405a Add a command line program for testing datagram reliability 2013-01-21 22:26:19 +00:00
a0457273b7 switch javadocs from bob.i2p to i2p-javadocs.i2p
(sponge no longer hosts them)
2013-01-21 01:56:14 +00:00
e6a330944d update oracle package-list URLs 2013-01-21 01:44:10 +00:00
20940f209b Lower log level 2013-01-20 21:23:06 +00:00
bbc71ad13c Some refactoring 2013-01-20 21:21:53 +00:00
64917757a4 Make delivery checking turn-offable 2013-01-20 21:21:36 +00:00
b966ebbcfd address.tag: replace hover with click-to-expand; share code with editIdentity.jsp 2013-01-20 19:49:23 +00:00
ca7f4124c4 Update en and de strings 2013-01-20 16:13:42 +00:00
b24fe46661 Fix ambiguous i18n source string "Sent" 2013-01-20 16:11:32 +00:00
1db3aee096 merge of '05f071f4da46716c5566db81c177ec3e3ec04852'
and 'de9594e3f85d2d2401af64407c0c54c4e6a61d33'
2013-01-20 03:02:17 +00:00
db5a566e15 Language nb is more precise than no. 2013-01-20 02:53:01 +00:00
f485c68472 DeliveryChecker.java:
* Don't save metadata unless it changed
 * Logging
 * Code formatting
2013-01-20 02:28:41 +00:00
78013d6725 Wait until connected to DHT 2013-01-20 02:20:51 +00:00
261d05a1d6 Prevent "${param.path}" from showing up as a translation string 2013-01-20 02:15:17 +00:00
4a79a28d28 Handle tags that have an attribute but the message key is in the body 2013-01-20 02:02:51 +00:00
844a7a24fe Add help text to editIdentities.jsp 2013-01-20 01:28:23 +00:00
9937ec73f9 Remove more mockup elements 2013-01-19 23:32:30 +00:00
54629d8d05 Appearance changes to sendEmail.jsp 2013-01-19 23:28:19 +00:00
15dcd78936 Show whether an email has been replied to 2013-01-19 23:21:00 +00:00
087a4a68be Remove an extra '<' 2013-01-17 23:10:03 +00:00
7829c44d0d Add a delete button after replying to an email 2013-01-17 22:57:15 +00:00
476d06a588 German, French, Italian, Polish, Portuguese, and Russian translation updates from transifex 2013-01-17 12:43:25 +00:00
53223be28d Display an error if no public name entered 2013-01-16 22:27:27 +00:00
691b8ade1c Bump version to 0.2.7; migrate metadata files 2013-01-16 22:14:08 +00:00
7ac255ec94 Encrypt metadata files (as of rev 24af3e..., they contain email destinations and packet keys) 2013-01-16 22:05:35 +00:00
cf84a6aeee Don't receive packets as streams 2013-01-15 21:18:50 +00:00
15c45ad820 Remove unused import 2013-01-15 20:53:49 +00:00
10100b8177 Synchronize a method I missed in rev 7db2932b3db6bbf32d4ae937c93eb37e06e9f099 2013-01-15 20:51:51 +00:00
6adef679ac Synchronize CryptoFactory (Ticket #610) 2013-01-14 20:16:04 +00:00
00411877ad Change log level 2013-01-14 20:10:33 +00:00
7dc9f6caa0 Change log level to DEBUG (same as the other background threads) 2013-01-14 20:09:57 +00:00
dcb2b0f945 Translate page titles 2013-01-14 20:00:06 +00:00
f396729698 Disable "default" checkbox when there are less than two identities 2013-01-13 21:15:07 +00:00
0aff058acd Add a note about automatic email checking when a password is set 2013-01-13 21:00:12 +00:00
55f363aa73 Add @Overrides 2013-01-13 20:48:27 +00:00
6fec35ce85 Remove unused methods 2013-01-13 20:45:13 +00:00
42001079b5 Don't show private key link when creating a new identity 2013-01-13 20:42:35 +00:00
ab3d23a3af Fix variable name 2013-01-13 20:38:29 +00:00
3b0c9774e5 Remove mockup elements 2013-01-13 20:35:39 +00:00
8b44166b90 Simplify stringification 2013-01-13 20:12:55 +00:00
46ca0add8a Shorten thread name so it doesn't get truncated in the logs 2013-01-13 20:09:58 +00:00
6e967b2365 Fix: Version number not correctly written to file 2013-01-13 20:05:15 +00:00
bc72ebb865 Implement delivery status feature 2013-01-13 17:25:01 +00:00
e204d01fa2 Remove a System.out.println() 2013-01-12 02:51:39 +00:00
4a05868f11 Catch a more specific exception 2013-01-12 02:44:11 +00:00
6400913229 Move remaining third-party code (flexiprovider, lzma, and scrypt) into .jars 2013-01-12 02:42:00 +00:00
d7d3f2f01c Update to NTRU 1.2; move NTRU into a .jar 2013-01-12 02:08:08 +00:00
f9014d7b7b Fix unit test 2013-01-07 15:02:32 +00:00
a64ece90c2 Sort relay peers 2013-01-07 15:02:16 +00:00
e8f16cc83c Remove an unused method 2013-01-07 15:01:36 +00:00
d7b7355dd1 Fix warnings 2013-01-07 15:01:15 +00:00
816cf49b8c Get rid of the I2PBoteThread mechanism and handle thread interruptions correctly 2013-01-05 22:07:38 +00:00
bf2e2224c9 More detailed log message 2013-01-03 13:45:06 +00:00
2824c9a773 Minor comment change 2013-01-02 23:35:04 +00:00
1dbbcd8b78 Fix: themes not found because directory names were localized 2013-01-02 23:34:35 +00:00
d7d6257a36 Add an import for JavaDoc 2013-01-02 21:28:57 +00:00
020ef33b95 Log exceptions 2013-01-02 21:28:21 +00:00
8cfe4c5660 Only send up to 20 peers in a PeerList 2013-01-02 21:27:27 +00:00
e04deb28a1 Add info on how to set up Eclipse 2013-01-02 21:23:56 +00:00
fc0837ede4 Fix identities file name; change some wording 2013-01-02 21:20:22 +00:00
zzz
3ade199175 Specify source=1.6 target=1.6 so we can build with Java 7.
Suppress ant warning.
2013-01-02 12:53:28 +00:00
zzz
7bffe19e9e merge of '9030eb5d24f9d9f0c546f54c8a078749941e28df'
and 'ec0ec8bca6aa7c8d6b314688662891ed0c80aa34'


Merge broken rev from asaf.
Mtn 1.0 can't handle dates with trailing time zone indicators,
such as 'Z'. asaf's checkin was done with guitone which
adds the 'Z'. Hopefully this will make mtn 1.0 happy again.
2013-01-02 12:38:22 +00:00
3ffcf9d8d3 Update German translation from Transifex 2012-12-30 15:52:52 +00:00
111b3d8dbb Add a heading and a brief explanation 2012-12-02 14:27:31 +00:00
e177cd4567 Comments 2012-11-27 17:43:19 +00:00
a0ce9017a9 Include file size in log 2012-11-27 17:39:08 +00:00
bc1848ddcf Add a few more classes from the upstream bouncycastle jar due to recent changes in I2P.
Fixes the error found at http://pastethis.i2p/show/fnVXfo6eWaq4uaQNUjhO/
2012-09-25 23:02:14 +00:00
1f595fc079 Change "New" button text to "Compose" 2012-08-14 18:27:29 +00:00
22c0b789c4 Display last mail check time 2012-08-14 18:23:47 +00:00
967286aed0 New Arabic translation from Transifex
100% complete
2012-08-09 14:00:31 +00:00
ef357a5f2a Updated German and Spanish translations from tx. Pushing en source files to tx. 2012-07-29 10:03:47 +00:00
9fb05ba42e Remove a wrong comment 2012-07-20 12:00:29 +00:00
f13743d7b9 Make the "error" status text a link that shows a stack trace 2012-07-20 11:58:32 +00:00
549c39681d Lower log level 2012-07-20 10:56:09 +00:00
a3e8f657dd Show connect button if connecting failed 2012-07-20 10:54:35 +00:00
9cb3409a1a Add KYTV, change HH's role to Main Dev 2012-07-20 10:53:08 +00:00
5e87d6fa2d Lower log level 2012-07-19 15:16:35 +00:00
902db81fa7 Disable streaming 2012-07-19 15:15:17 +00:00
3cd0f09a41 More detailed log message 2012-07-19 15:13:27 +00:00
d0204effa2 Scroll down to the plugin section 2012-07-19 15:12:48 +00:00
ec619dd830 Fix: some threads not terminating on interrupt() 2012-07-19 15:08:52 +00:00
10e3df428c Spanish translation update from tx 2012-06-06 10:11:49 +00:00
e11f41d7f2 merge of '6f90a7d3635c3fece552972c32e378fc5177dd0b'
and '754beaa17f082deb32703c671277a2c0a5ef9ae5'
2012-06-03 21:37:14 +00:00
f7aae2de4e Add Hungarian translation from TX, thanks AdminLMH! 2012-06-03 13:57:06 +00:00
d1e4d1a715 Apply layout fixes from rev. e3deccd7238bb85c8b21b564b52979e3b3441142 to network.jsp 2012-06-03 09:38:15 +00:00
9435b23ab2 Internationalize a string 2012-06-03 09:23:05 +00:00
bdffd2b8c4 Apply layout fixes from rev. e3deccd7238bb85c8b21b564b52979e3b3441142 to the vanilla theme 2012-06-03 09:19:50 +00:00
590b9a9e05 Handle individual files 2012-06-03 07:20:36 +00:00
86ec61db22 Fix layout issues in recent versions of Firefox and Chromium 2012-05-24 18:33:04 +00:00
45f60e9242 Add translators 2012-04-20 00:11:08 +00:00
56be74a167 Dutch updates from Transifex 2012-04-19 23:31:06 +00:00
14376afddb Translation updates from TX (cs, de, es, pl, & sv) 2012-02-23 12:17:55 +00:00
d2adcd64a7 Fixed bug with "Check mail" button.
Better presentation for "Compose" button.
Some advantages in russian translation
2012-01-01 00:00:00 +00:00
13c19addff copy theme folder 2011-12-17 00:37:29 +00:00
dad6a579c1 Escape & entities 2011-12-17 00:37:15 +00:00
83d585f651 s/wordwrap/word-wrap/ 2011-12-17 00:36:56 +00:00
90ceef4583 Add the ability for users to add their own UI themes 2011-12-15 06:51:16 +00:00
0bf899e291 Update translation 2011-12-14 02:48:25 +00:00
bbdfc5745b * Add theming support
* Add 'vanilla' theme
* Remove unused icon files
2011-12-14 02:44:22 +00:00
c3e6a437c9 HTML/CSS:
* Move CSS out of JSPs
 * Replace layout tables with CSS
 * Make pages variable width
2011-12-10 05:08:12 +00:00
dbe4400409 Internationalize strings 2011-11-27 06:26:59 +00:00
bb5d075a54 Replace no-argument JSP functions with bean properties 2011-11-27 06:01:53 +00:00
5d87d5ec00 Put close() in a finally{ } 2011-11-26 05:06:39 +00:00
d24eea365c Add comment 2011-11-26 04:57:35 +00:00
abd4a55956 Move the two toByteArray methods into the superclass 2011-11-26 04:55:00 +00:00
732b14115b Fix error message 2011-11-26 04:39:13 +00:00
4455fbb172 * Move symmetric encryption to AbstractCryptoImplementation
* Don't use deprecated methods AESEngine.safeEncrypt() and AESEngine.safeDecrypt()
2011-11-26 04:31:35 +00:00
673d43cd86 Use the global context, don't create a new one 2011-11-24 05:23:02 +00:00
b45a162826 Updated (ant poupdate) and pushed to tx 2011-09-23 19:23:44 +00:00
b06d07b5d1 Add Vietnamese language from Transifex 2011-09-23 19:23:16 +00:00
52ac133ffa Add Italian and Ukrainian from transifex 2011-09-23 19:17:23 +00:00
4a240fbb5b Ran ant poupdate for ar and fr. These have been pushed to transifex. 2011-09-23 19:16:52 +00:00
252a7f0dad merge of '6e3866d554a0bce90773691091c5e037aa69cadc'
and '95a0846bd260b60d641a584dceb6ced27aa2e3ce'
2011-09-23 19:01:36 +00:00
1cd51c811d display tooltips in routerconsole 2011-07-20 04:15:26 +00:00
dda1f5b585 corrected version in manual to current release 2011-07-20 03:46:22 +00:00
fb5e1fc4c2 upd i2p-bote messages_fr.po 2011-07-08 14:39:57 +00:00
0e6a32a0a0 Update Arabic po from source and finished translation 100% 2011-06-11 09:23:59 +00:00
d9bc25e1aa translate French strings into Arabic 2011-06-09 13:57:26 +00:00
b124a1046d update .po's 2011-06-02 18:47:29 +00:00
cd21435b60 correction to history.txt 2011-05-02 16:29:02 +00:00
44130323ad typo es 2011-05-02 16:28:38 +00:00
ef339c29d0 Fix: Existing derivparams file not found 2011-04-30 22:28:56 +00:00
8ea8e86d99 Correction to translators 2011-04-30 18:45:46 +00:00
0edf2cfbe3 Replace b32 url with i2pbote.i2p 2011-04-30 18:25:15 +00:00
a4b284a71c 0.2.6 2011-04-25 23:36:22 +00:00
e1b9eb5bbc When replying to an email sent by a local identity, send to the recipient of the original email by default 2011-04-25 00:22:33 +00:00
f45a185502 Update techdoc.txt; remove To Do / Ideas section 2011-04-24 15:06:40 +00:00
be545c0836 Don't run migration if already migrated to the latest version 2011-04-24 15:06:39 +00:00
6c10b8ac64 Fix: signature flag (Email.SIGNATURE_VALID_HEADER) not set on emails in the "sent" folder 2011-04-23 23:35:23 +00:00
92ff6b58f0 Add FileInfo tool 2011-04-23 22:16:26 +00:00
1f54ed9ba8 Change order of parameters in the derivparams file so it matches encrypted files 2011-04-23 21:36:47 +00:00
19452867b4 Fix error messages in log: "Request contains a parameter named recipient0, but no parameter named recipientType0." 2011-04-23 08:35:22 +00:00
1fe6c4fc36 Move illegal <description> tags out of i2pbote.tld 2011-04-23 07:15:44 +00:00
57ead77d39 Capitalize static variable 2011-04-23 06:29:46 +00:00
dd3ed14174 Remove empty directories (see rev. 65aabb15c2a5df2959bdd8987b6ef8959fe3a537) 2011-04-23 06:23:43 +00:00
efc2363ade Translate page title 2011-04-23 06:01:24 +00:00
19a586b170 Integrate FAQ and user guide 2011-04-23 05:59:54 +00:00
3851faff3f Fix a few things in the German translation, and make it more German 2011-04-22 21:29:08 +00:00
a583a1fcc3 Add/fix comments 2011-04-22 20:58:41 +00:00
0464c76884 Wrap (fold) long signatures 2011-04-22 08:28:14 +00:00
2bc05d4d46 Use identities from TestUtil 2011-04-22 07:18:25 +00:00
19970b1d53 Fix: "Check Mail" button brings up an error page if a password is required 2011-04-22 05:54:48 +00:00
035cd346a4 Fix: "constant string too long" when compiling tests with Ant (javac) 2011-04-21 04:56:04 +00:00
cb1d5bbf67 Set encoding to ISO-8859-1 when compiling flexiprovider sources 2011-04-21 04:50:54 +00:00
058d09d262 Pare down flexiprovider some more 2011-04-21 04:48:05 +00:00
14c728c588 merge of '110cd0892a45b8d875bce780895a137da24510d8'
and 'df7b1ac4e3f00852ae445bab6259fb76bd56c5b6'
2011-04-20 03:08:49 +00:00
7823b38d24 Update russian translation 2011-04-19 17:44:33 +00:00
cb76489c0f Use SHA-512 for ECDSA-521 2011-04-18 05:57:28 +00:00
fb0352cd7e Don't create zero-length packet files 2011-04-17 19:22:46 +00:00
b7fcbb5829 Fix plugin target 2011-04-16 22:03:16 +00:00
80a04a70cb Fix IdentitiesTest 2011-04-16 04:58:40 +00:00
b48534b5f7 * Fix: endless JSP forwarding loop when two emails in the same folder have been encrypted with different passwords
* Make PasswordException a checked exception
* Remove unused method AddressBook.iterator()
2011-04-16 04:57:53 +00:00
a1085909e1 ego inflation 2011-04-07 21:50:23 +00:00
dc7777be7f fix about identity creation 2011-04-07 08:20:48 +00:00
0ed58252d9 fix about identity creation 2011-04-07 07:31:13 +00:00
660b77c112 fix about identity creation 2011-04-07 07:15:44 +00:00
1c2fe9a481 typos 2011-04-06 19:37:47 +00:00
dc2d8397ab ug_fr.html saved as manual_fr.odt 2011-04-06 13:20:04 +00:00
926a06e53c end (0.2.6) 2011-04-06 13:03:08 +00:00
7de621dc82 end? 2011-04-06 08:55:16 +00:00
35bf2b930a still wip 2011-04-06 07:24:31 +00:00
307e4e8863 fix Guide 2011-04-05 23:33:57 +00:00
04569977d5 still wip 2011-04-05 18:40:39 +00:00
b11bd7b53b small fixes 2011-04-05 18:16:59 +00:00
4f42050cf2 wip 2011-04-05 17:13:49 +00:00
4b95f34430 wip 2011-04-05 12:22:12 +00:00
e10933cc0e typos 2011-04-05 11:03:54 +00:00
db4c3f23cd wip 2011-04-05 11:03:10 +00:00
3ff443fcc8 upd 2011-04-05 10:28:29 +00:00
3c302441ea upd 2011-04-05 08:32:19 +00:00
250f12a69f upd 2011-04-05 07:50:20 +00:00
cc15bff91b add 2011-04-05 07:24:31 +00:00
9b8828109c testers 2011-04-03 21:43:58 +00:00
72e033e2ef merge of '8bc35fe3851864fad1642e80e73229d6c14d1ba7'
and 'e2e8fcdb307d607cd9d22db33030468d94ec1883'
2011-04-03 20:17:22 +00:00
08f96661fa endend 2011-04-03 19:10:25 +00:00
7bfffe413c Update to BouncyCastle 1.46 which fixes a bug in ECDSA 2011-04-03 06:51:59 +00:00
1425a641ae merge of '4fc6f4c8c7963990ab7f079b86d96b7b8aeb761d'
and 'fd7b2809cdc6fa75aacb97c2ed09a2df4101f41f'
2011-04-03 04:41:16 +00:00
8ed88d1331 ECDH_ECDSA.java:
* Remove exceptions that are declared but never thrown
 * Remove safeEncrypt() TODO, not worth breaking compatibility
2011-04-03 04:40:05 +00:00
a99c08d0e7 typos 2011-04-03 02:17:32 +00:00
c1191d803c translation tweaks es, pt 2011-04-03 00:30:14 +00:00
844f1d3741 translation tweaks es & pt 2011-04-03 00:20:57 +00:00
612753b39e Fix: message not showing when an identity is deleted 2011-04-03 00:11:41 +00:00
cecccddc2e translation tweak es 2011-04-03 00:08:56 +00:00
17073ed8cd translation tweak es 2011-04-03 00:01:19 +00:00
efe14faae4 Move "delete identity" link to editIdentity.jsp and replace the trash can icon with a "delete" button to make it harder to accidentally delete an identity 2011-04-02 23:14:22 +00:00
08aa68d257 Suppress echoing of .bat commands during JRE installation, show a wait message instead 2011-04-02 23:03:12 +00:00
2b9b19030f Undo rev. fcd151e70c681bd38f2677cf4e9be334c7ca4cbe which broke win32installer 2011-04-02 22:27:39 +00:00
87b70ff7bc merge of 'e1744d66f44b6c2f5d1b7d6c2d337c5f2db49687'
and 'fcd151e70c681bd38f2677cf4e9be334c7ca4cbe'
2011-04-02 17:16:21 +00:00
6776b87040 update Swedish translation; thx to hottuna and jaywalk 2011-04-02 12:39:44 +00:00
210ad7f767 Dutch translation updated 2011-04-02 11:34:48 +00:00
3960e41534 Transifex config 2011-04-02 11:26:06 +00:00
32fc56754a Add support for Transifex, fixing po errors. 2011-04-02 11:24:30 +00:00
082f553be4 Create i2pbote.jar in ant_build/lib instead of WebContent/WEB-INF/lib 2011-04-02 02:44:20 +00:00
bcb31dca0a merge of 'a887eef6899db3400a21fb2319e61208d91cbb29'
and 'b156a7cf0018eebcf3ca07c4273a7918ef260ce7'
2011-04-01 19:55:53 +00:00
a508fa1a0f update translations from web-based translations for sv and zh 2011-04-01 19:55:22 +00:00
dbf769a8cb end2 2011-04-01 14:30:28 +00:00
f3825f3890 end 2011-04-01 12:48:58 +00:00
4125ada488 typo 2011-03-31 19:28:24 +00:00
6a425d1880 merge of 'a11d73c48aa593549c58e0caf94c3effd46ad971'
and 'a7d2d9270b5d91a90992345375b12bd392697635'
2011-03-31 01:28:44 +00:00
173c89306f go on and go2bed 2011-03-31 01:23:06 +00:00
8c6e3bedfb go on 2011-03-31 00:47:01 +00:00
db9a13d58d go on. Please user have a look...I PM my 2 questions 2011-03-30 23:38:51 +00:00
fa37238e00 update translation es and pt 2011-03-30 21:07:40 +00:00
2f10c2bb29 update FAQ and Manual 2011-03-30 20:16:16 +00:00
437686b1e6 redo 2011-03-30 19:41:45 +00:00
53508009b9 upd 2011-03-30 17:01:08 +00:00
49ff872b88 go on FAQ_fr 2011-03-30 11:24:38 +00:00
115688de03 begin 2011-03-30 09:17:51 +00:00
346d0cd822 Fix remaining file deletion issues on Windows (see rev. 10d16759d75f1ee7ddcbe3bbf16a826d21345619) 2011-03-28 07:56:28 +00:00
e51c29565e Don't report an error if there is no metadata file 2011-03-28 07:43:49 +00:00
15f209844d Internationalize string 2011-03-28 07:38:11 +00:00
86a50c7986 Update win32installer to work with latest router install.xml, add flexi-gmss-1.7p1.jar 2011-03-27 06:50:46 +00:00
5d44198fef Update German translation 2011-03-27 06:49:38 +00:00
3ab31b8b16 Don't log stack trace when plugin.config not found 2011-03-27 06:48:53 +00:00
4bbab19d14 If no good relay peers are known, query for peers more often 2011-03-25 00:34:24 +00:00
d532c6117d Replace NtruSign with GMSS which uses smaller public keys and inspires more confidence security-wise 2011-03-24 04:38:21 +00:00
63dc3ea208 Fix: Identities and address book still available after the Clear Password icon is clicked 2011-03-16 22:10:00 +00:00
82cb40e9bf Check for null values from I2PSession.receiveMessage() 2011-03-16 19:11:27 +00:00
ec0b072fca Refactor / cleanup:
* Reduce visibility of classes and methods
* Remove unused methods and commented-out code
*
2011-03-16 19:09:57 +00:00
4718424d11 Fix: "Password cleared" message not showing 2011-03-16 17:05:26 +00:00
4300ce67e8 Fix NPE in clearPasswordCache.jsp when password is not in cache 2011-03-16 15:33:11 +00:00
c58a8bb562 Add null checks 2011-03-16 04:30:56 +00:00
55859d669b Remove unnecessary instance variables 2011-03-16 03:51:11 +00:00
e11e80832a Update German translation 2011-03-16 01:31:47 +00:00
e5f7e1e78f Show an icon when the password is in the cache, and uncache the password when the icon is clicked on 2011-03-16 01:25:02 +00:00
6893f5b487 Remove unused constructor UniqueId(InputStream) 2011-03-14 06:20:10 +00:00
d56ccaf436 If Seedless not available, continue trying 2011-03-14 06:18:26 +00:00
1110bbe386 add credits 2011-03-12 03:36:16 +00:00
65290098e6 Add an option to show the full email identity (public + private keys) 2011-03-08 05:33:53 +00:00
5fd314753b 2011-03-08 05:20:56 +00:00
8dd98f2733 Update russian translation 2011-03-07 19:34:05 +00:00
d33882848f Include encrypt.bat and decrypt.bat in the plugin install (I missed this in rev. 01eb620588f85f0d86184be1fb349a43a83fbcfb) 2011-03-06 22:56:56 +00:00
0e174f870c 2011-03-06 22:08:02 +00:00
6954e5c7a8 Change /passive option to /s 2011-03-06 22:04:39 +00:00
8de6a0ab07 Update JRE download link to 6u24 2011-03-06 22:04:00 +00:00
d7cf897072 Add launch scripts for the Encrypt and Decrypt tools 2011-03-06 21:05:09 +00:00
596d19d212 * Add command line programs Encrypt.java and Decrypt.java
* EncryptedInputStream: throw a PasswordException if AESEngine.safeDecrypt() returns null
2011-03-05 23:21:22 +00:00
4e44fc204e merge of '0c43ec8566a97f8ad57f17575db898b259932435'
and '662195feb3df61d6b5a84dea177727d94cedb8b6'
2011-03-03 21:23:00 +00:00
277a535be4 l8tion 2011-03-03 18:13:39 +00:00
1dbd6ebc4c Add Override annotations 2011-03-03 03:46:25 +00:00
bcf869586f Update comments 2011-03-03 03:41:33 +00:00
6b5bc59775 Update techdoc.txt 2011-03-03 03:38:55 +00:00
17feb49b0a Fix: Cached scrypt params and salt not correctly reused 2011-03-02 01:51:21 +00:00
9625566913 update zh translation
adapt gettext script to work under windows:
set $LG2 to update/build ONLY with the language you want.
2011-02-28 06:13:51 +00:00
b2a3308c2e Ignore blank lines 2011-02-28 05:30:55 +00:00
89e5a195f8 Remove extraneous character from destination key 2011-02-28 05:30:41 +00:00
e4c130f51f merge of 'c2a5904fdb10cc3d4cbfa195c557c06cf2f65b5e'
and 'e32e7d661f1c0e4ba49afe94f9b2d89acd40e0d5'
2011-02-28 04:59:29 +00:00
899c0f6796 add credits 2011-02-28 02:11:18 +00:00
fc1287a016 add 安全,分布式电子邮件 and بريد الكتروني الآمن و الغير متمركز 2011-02-28 01:49:40 +00:00
fd3ca21a0c 2011-02-27 23:58:52 +00:00
789f8ddc3f If the forwardUrl parameter is not present in an ib:requirePassword tag, go back to the originating page after password entry 2011-02-27 19:51:50 +00:00
bda40109ed Don't show the "known" and "signature" columns in the sent folder 2011-02-27 17:09:42 +00:00
8c44d3890d Replace PBKDF2 with scrypt 2011-02-27 06:15:53 +00:00
0e2b89dff1 Fix: Duplicate identity created if password was not entered beforehand 2011-02-27 06:07:46 +00:00
7c46127738 fix and update .po's, update de,es,pt,fr 2011-02-27 04:40:42 +00:00
d33b8da111 Fix: PasswordException never thrown when saving/deleting an identity 2011-02-19 20:56:02 +00:00
5d6c30f0bb merge of '4e3d88847518753370c65b8240f9f8a623bb3834'
and '9a74d7db99343b21d83e1fb4d89977feb4b541d2'
2011-02-19 19:37:05 +00:00
7008c26545 Show a wait page if an email identity will take long to generate 2011-02-19 19:36:25 +00:00
b8597014dd Fix anonymous sending of emails 2011-02-17 03:55:16 +00:00
0457bd307f Refactor:
* Rename package i2p.bote.io to i2p.bote.fileencryption
 * Move DHT packets to the DHT package
 * Move relay packets to their own package
 * Move ExpirationThread to i2p.bote.service
 * Rename RelayPacketTest to RelayRequestTest
2011-02-17 02:23:10 +00:00
eb446f8703 Add Arabic translation of the plugin 2011-02-16 19:25:19 +00:00
9df307365c Show attachment sizes 2011-02-14 03:12:05 +00:00
fcd4fb63ed New CryptoImplementation: NTRUEncrypt1087_NTRUSign349 2011-02-14 00:11:37 +00:00
27713fb7b6 Remove unused method 2011-02-13 19:23:58 +00:00
0db3ce5026 Make the default status translatable 2011-02-13 19:14:54 +00:00
0f04c2c51a Display an error if the attach button is clicked and no file is selected 2011-02-13 16:35:11 +00:00
206be17615 Show the first few characters of the email destination in the "From:" drop-down 2011-02-13 06:08:26 +00:00
2511c5b851 2011-02-13 04:34:23 +00:00
4db98b2c2b Fix RelayPacketTest 2011-02-13 04:31:05 +00:00
8d2d360180 Fix email deletion on Windows 2011-02-13 03:50:19 +00:00
7d7b509eb9 initial translation for chinese 2011-02-10 16:02:26 +00:00
124ca1ba62 Inform user when an update is available 2011-02-05 23:24:52 +00:00
e9cd4a9f6c * Send big packets as a stream
* Don't rely on InputStream.available() in Util.readBytes()
2011-02-05 16:10:41 +00:00
c627299a35 Fix: All input after first flush() is dropped 2011-02-05 15:53:56 +00:00
e0f183efa8 Comments 2011-02-02 19:30:09 +00:00
89395885ba Fix a NPE 2011-02-01 05:41:53 +00:00
a77309ab36 Change constant scope to private 2011-01-31 07:33:03 +00:00
efd04f322c Remove unused method getMaxFragmentSize 2011-01-31 07:09:42 +00:00
a12f90d432 merge of 'a0f3953b8929001edc2b9d59c3bf314040fc4c7b'
and 'fd9b359f0a1eb07fcc4c0c8ec5abe95a0bc073dd'
2011-01-11 19:29:29 +00:00
5919da4930 merge of '62dcd55b7726aedd5624b076d838cbd11787695a'
and 'cb7ee59eaf0eb93c0dcb91a8226591ca01e51342'
2011-01-11 19:22:47 +00:00
2d291f1ce2 added credits 2011-01-02 05:45:53 +00:00
e299d2e83d Quick fixes to Swedish translation. 2011-01-01 21:54:22 +00:00
76551e3d3f Added Swedish translation. 2011-01-01 21:47:34 +00:00
2f134bfbe4 add translation to Norwegian 2010-12-31 07:01:23 +00:00
c03c481b94 merge of '9a8a529946e94b430d154a127ca08010f15d66d5'
and 'cc0e869985b06631a79b60bf1060d86cc0e88afd'
2010-12-31 01:09:35 +00:00
7d1fed76da mods to pt 2010-12-29 15:51:57 +00:00
7148172e9c New unit test: PasswordCacheTest 2010-12-22 06:01:17 +00:00
5c102da3a0 * Reset expiration when a password is set
* Clear derived key when password is cleared
2010-12-22 05:49:18 +00:00
f3a1c618e5 merge of '243e68f714882dc1fe2f79958b31ac862053ba9f'
and 'f9ab92a43553dde223bb24940d32f19a60022b34'
2010-12-20 05:38:39 +00:00
5c221f31d9 Add missing copyright notices 2010-12-20 00:42:37 +00:00
7ac42c0e4e translation updates 2010-12-19 23:32:17 +00:00
4da3ee6aed New Ant task: win32installer 2010-12-19 23:00:50 +00:00
3aecc56933 Restore plugin.config after mismerge 2010-12-19 22:27:47 +00:00
5ea124b7d2 Jetty fix 2010-12-19 22:22:17 +00:00
7fb33a0d35 Fix return to folder.jsp after password entry 2010-12-19 22:21:04 +00:00
6d2878db5c * Add jMock .jars to JUnit classpath
* Offer to download JUnit and jMock if they're not found
2010-12-18 03:46:00 +00:00
9bee5057f1 merge of '0b216d7818b91cf69fdfb88048dfcbfbfce02833'
and 'de95731855e9e7f8a81b42642fd566ac6ee76c08'
2010-12-17 19:54:42 +00:00
bdce2ecad5 merge of '561ea16dc8eb82dc348dca962f30e579c8ed3d63'
and 'b1b87fc5a28b9aad267b6c3aeddc1c23377c5ab6'
2010-12-17 19:54:42 +00:00
d3ee66ff60 * Remove unused method toBase32
* Replace instanceof with getClass() in equals()
2010-12-17 03:43:44 +00:00
647efead3b Fix unit tests; jMock now required to run them 2010-12-17 03:41:57 +00:00
09f5d107c9 translation update de 2010-12-17 02:01:47 +00:00
d33bc11a31 Contributors update 2010-12-16 01:27:09 +00:00
2d6066ad58 Remove serialVersionUID from non-serializable class 2010-12-16 00:40:21 +00:00
0bdd216ef0 Remove an obsolete comment 2010-12-16 00:39:08 +00:00
75336e899d Fix an import 2010-12-16 00:28:22 +00:00
3870ca5335 plugin.config nl link translation 2010-12-13 18:46:26 +00:00
5aaae853af plugin.config translation 2010-12-13 16:39:01 +00:00
a64cdca34e merge of '0039d7fd449038234648a57ff05906383d0ce75d'
and '92c193a4f6709ce5205a43617bcd8a144ae598ca'
2010-12-13 11:52:48 +00:00
99f64adc05 merge of 'b85935006af43967ba763bb53ab75c6f0278c539'
and 'eff65f71bc633578ad72cbcb2d5301f1d1766c30'
2010-12-13 11:52:47 +00:00
05c24ab545 explicit merge of '93973b70de2d4a41180a7d2f201b684e5ea6d445'
and '451bb8a70baa411c0d401c329b5b60b7c14d09b3'
2010-12-13 11:44:04 +00:00
897d43ff51 Fix a typo 2010-12-13 11:42:56 +00:00
46b9e3a039 explicit merge of '7ca94be8ef990b10920f144f441a51d239d33c48'
and 'ef38ab9835eb8fec5dbd981f2951d12d5d0d5d0d'
2010-12-13 08:06:21 +00:00
018209bed5 Dutch translation by KwukDuck 2010-12-13 08:03:04 +00:00
fe14f97dfd explicit merge of '5c7fd9edde41ff7c26cd2fb28e1a46b96c1f8538'
and '9245efd7b168684236148a7102535f0a009e2c4f'
2010-12-13 01:39:10 +00:00
f2b1d3cc1c Portuguese translation 2010-12-13 01:13:25 +00:00
0600b6e595 merge of '08eff6bfa6a2b340f314f1de096c771337eb3a3b'
and '1dbb023c5b2674f49708ad83060aed35cdb3a7a1'
2010-12-12 20:10:11 +00:00
aab0b139d3 * Don't encrypt meta files
* Don't attempt to convert a non-existing directory
2010-12-12 20:06:18 +00:00
872c386929 Focus the "old password" field 2010-12-12 20:03:19 +00:00
23f57da28e * Cache file encryption key, reuse salt for performance
* EncryptedOutputStream: Cache key, not password; keep a copy of the key until close() is called so the key is not lost when the original is erased by PasswordCache
* Prevent password expiration during password change (which can take some time)
2010-12-12 20:01:09 +00:00
7fbd29b75d File encryption 2010-12-10 20:10:49 +00:00
b8fd5b5c1d Add TO-DO note for HH to do an important fix. 2010-12-07 00:36:20 +00:00
c81f2cb46c merge of '43b11afe7287401107616e5cff0c1d4773c0e1d3'
and '92344efb7a96786e8ef1e256f754ea8e9666c765'
2010-12-07 00:23:23 +00:00
6c859388c5 changes to Spanish translation 2010-12-04 10:56:38 +00:00
087b8ddc42 changes to the manual 2010-12-04 10:52:54 +00:00
0eba059a8c merge of '28760fe7e19dd265a2ede35a51f73e5c07b1a2aa'
and 'db84face38fdd977157aaf02c444b894c7049d84'
2010-11-28 06:45:44 +00:00
7136ab215c Refactor out Deprecated destFromName calls, fixup nb files 2010-11-28 06:45:22 +00:00
3f867d8041 plugin.config: add russian translation 2010-11-20 19:29:23 +00:00
a8bb3652fe added string to plugin.config and a minor correction 2010-11-16 22:34:07 +00:00
1672d95ae6 merge of '2e376f13320c297b93e734b3f39e113752891578'
and 'f2d47e61537a5a2f2077eae200af07ef12114b2e'
2010-11-11 21:01:03 +00:00
c3c832649c update manual 2010-11-11 21:00:10 +00:00
c115278016 merge of '6b7cd0a43c55b9a2ae53778a25e6940cfe4fba1f'
and '9245efd7b168684236148a7102535f0a009e2c4f'
2010-11-11 17:32:29 +00:00
a65653b30b Spanish translation for Bote; fixes sent in by Redzara to French translation 2010-11-11 17:31:18 +00:00
d92f66720a merge of '37af2db09b85c46e860280cdb70d92bf07810401'
and 'df5454597876a5df6f61e5adb97d30fb57b63d48'
2010-11-04 06:57:33 +00:00
0954398245 minor corrections 2010-11-03 18:10:46 +00:00
50da5ccc80 Fix a NPE 2010-11-03 06:09:00 +00:00
2b71438c82 French translation by albat and mixxy 2010-10-29 20:19:23 +00:00
1b5356e845 Fix a comment 2010-10-26 20:24:52 +00:00
9c951dc2f1 Fix a NPE 2010-10-26 18:27:11 +00:00
117c35cc5a * Sign email before saving to sent folder
* Don't hide signature column in folder.jsp. It was a kludge, signing before saving is the right way to do it.
2010-10-14 19:02:11 +00:00
dbd46e2b4f Comments 2010-10-03 22:06:20 +00:00
a2c55a78fc 0.2.5 2010-10-03 22:05:54 +00:00
c423b7331e Implement KBucketTest 2010-10-03 21:59:48 +00:00
a031f4da28 Decrease text field width on the "new email" page 2010-10-03 19:19:15 +00:00
7573eed929 Minor things 2010-10-03 19:13:53 +00:00
1e78638692 Refresh folder list when new mail arrives so the inbox message count is updated 2010-10-03 08:07:48 +00:00
19ea512d79 Fix: Two new recipient fields appear when the "plus" button is clicked after entering text in the existing recipient field 2010-10-03 07:25:07 +00:00
b9155254d0 Use base64 for RelayPacketFolder filenames, which is what all other folders do 2010-10-03 00:19:14 +00:00
0ebe7e68c7 Update techdoc.txt 2010-10-02 22:50:02 +00:00
48340cb790 Update manual 2010-10-02 20:14:24 +00:00
02b803fda7 Fix duplicate "Unknown" in the date/time column in folder.jsp 2010-10-02 19:49:41 +00:00
4d306d5f85 Translation update 2010-10-02 19:47:05 +00:00
388843a439 Implement reading from ByteBuffer and writing to OutputStream 2010-10-02 18:34:56 +00:00
e03521821a Make the outbox check interval a config setting 2010-10-02 06:23:40 +00:00
ac77853485 Fix display of date/time in showEmail.jsp 2010-10-02 04:57:30 +00:00
ce664ebf8b * Use a non-deprecated variant of ElGamalAESEngine.encrypt()
* Do ElGamal/AES in the new methods Util.encrypt() and Util.decrypt()
* Use a min padding size of zero when calling ElGamalAESEngine.encrypt()
2010-10-02 03:51:59 +00:00
93041cb1d4 Simplifications:
* Get rid of RelayDataPackets, put everything in RelayRequests
 * Put a packet ID in all Communication Packets (most of them had it already)
 * Combine MalformedCommunicationPacketException and MalformedDataPacketException into MalformedPacketException
2010-10-02 03:00:53 +00:00
d68fd5429e Log deletion of relay packets 2010-09-30 05:50:03 +00:00
a7b4b9acc6 Pad relay packets 2010-09-30 05:11:42 +00:00
20841b7a4a Remove the unused and confusing Email Address field from the Edit Identity page 2010-09-27 05:54:08 +00:00
e7f186b7f3 * Write to metadata the time an email is created
* Add a "create time" column to the outbox
* Make "create time" the default sort column in the outbox
2010-09-27 05:37:27 +00:00
2a2adc6645 Change a few more logging statements I missed in rev. 6c3cec9cf9ac70dadd403a2f2bc10a5be18f1fbd to print peers in base32 2010-09-26 19:52:11 +00:00
9989940693 * Fix NegativeArraySizeException when a two-byte length field in a packet contains a value greater than Short.MAX_VALUE
* Keep packet size below I2PBotePacket.MAX_DATAGRAM_SIZE, take into account relay packet overhead
2010-09-26 18:51:49 +00:00
f71f0e1470 Show a message after saving settings 2010-09-25 07:32:00 +00:00
3c7bd9acf6 Simplify folderLink.tag by using folder.jsp for the outbox; see rev. 7790618d3eba2f460983f87db7ddc1fe1b94053c 2010-09-25 07:11:58 +00:00
1439358221 Take the user back to outbox.jsp after an outbox email is deleted 2010-09-25 06:48:31 +00:00
0895c3c976 Sort by name and destination, not just name, so different destinations/identities can have the same name 2010-09-25 06:45:53 +00:00
8a6c6c2627 Fix non-ASCII characters in the New Identity / Edit Identity form by changing it to POST (should be POST anyway) 2010-09-24 06:50:08 +00:00
c3883bb069 Make the "unknown" column a "known" column, show a check mark when an email dest is known 2010-09-23 05:52:06 +00:00
4e5104ff52 Show status for outbox emails 2010-09-23 05:29:22 +00:00
ecf093119a Reduce default delay to 5..40 minutes per hop 2010-09-23 05:04:26 +00:00
cbd7a8dffb Don't show signature column in "sent" folder 2010-09-23 04:57:37 +00:00
08cd5406f4 Sort address book and identities by name 2010-09-23 04:06:10 +00:00
af2f63565f Update technical documentation 2010-09-22 17:38:34 +00:00
1b481dcf24 Add user manual by mixxy, delete userdoc.txt 2010-09-22 17:38:15 +00:00
6ee5005944 Align Sent Time 2010-09-22 07:18:27 +00:00
b4b94ad38a Log peer destinations in base32 2010-09-22 06:21:57 +00:00
aa4551fc14 Show local destination and peer destinations in base32 2010-09-20 05:18:46 +00:00
9d77f57123 Add a note about attachment sizes 2010-09-20 03:31:11 +00:00
3115faedb2 Fix comments, remove unnecessary braces 2010-09-20 02:37:46 +00:00
4e7b0c115e Keep trying to send an email if there is an error 2010-09-20 02:27:33 +00:00
c28c99060b Replication:
* Replicate onto the closest nodes to the packet's DHT key instead of the local destination hash
 * When a packet has been re-stored since the last replication, assume it has been stored on all closest nodes and don't replicate it to any peer
 * When a delete request is received for a replicated packet, stop replicating that packet and replicate the delete request instead
2010-09-19 08:31:36 +00:00
d3a072c54b * Don't replicate packets that were recently replicated
* Log number of replicated packets
2010-09-16 05:06:44 +00:00
174a94f492 Fix: ReplicateThread.packetStored() not called when storing in a DeletionAwareDhtFolder 2010-09-16 05:02:12 +00:00
9f6806a738 Verify hashes of received email packets against the DHT key 2010-09-15 06:50:52 +00:00
809dc90bc8 Fix non-ascii characters (switching from Commons FileUpload to JavaMail-based multipart parsing broke them) 2010-09-09 06:04:40 +00:00
c14faf5fc4 Lower the LZMA dictionary size, 2^24 causes heap space errors when running as a .war in the router 2010-09-07 07:40:03 +00:00
d9034fee31 Change a few log levels 2010-09-06 22:56:27 +00:00
c30180fcbf Remove newlines from the end of files (just a personal preference) 2010-09-06 22:46:58 +00:00
110a4bd484 Fix LZMA dictionary size 2010-09-06 19:46:47 +00:00
06106c0b57 Use isProtocolVersionOk() for version checking, see rev. c848aa079ff8d62fac18c1c7782d48befc13b98d 2010-09-06 19:44:32 +00:00
a006e3b688 Use different texts for the two test emails 2010-09-06 07:53:18 +00:00
d37911e5b1 Add a new field containing a Return Chain to the Relay Request format. Only empty return chains are supported for now. 2010-09-06 07:10:35 +00:00
b128693296 * Talk to peers that use protocol version 4 or higher
* Do the version check in one place (I2PBotePacket.isProtocolVersionOk()), not two
2010-09-06 06:32:37 +00:00
85d958a0cc Add Russian translation by suhr 2010-09-05 19:59:11 +00:00
ca1d5e6d8c Update RelayPacketTest to use the new file format introduced in revision bfde50fb7c22410d7859a6914990798c68127bc5 2010-08-25 02:28:48 +00:00
245e50aaa9 Count emails with no metadata as new to match the behavior of the EmailMetaData class 2010-08-22 20:49:33 +00:00
4d0d5d245c Minor things 2010-08-18 20:58:51 +00:00
f1d8554ab3 Put a space between name and angle bracket 2010-08-18 20:56:42 +00:00
c76a33fa69 Fix: Extra blank char after the name when clicking "add to address book" in an email 2010-08-18 20:48:21 +00:00
5a3e49c4dd Replace Thread.sleep() with awaitShutdownRequest() 2010-08-18 04:33:57 +00:00
2ad8d2ac8e Fix: Folder view only shows the recipient if it is a local identity 2010-08-18 04:32:38 +00:00
d0c4fd7ca8 * Only use the last 20 peer list requests / responses to calculate reachability
* Increase RelayPeerManager.UPDATE_INTERVAL to 60 minutes
2010-08-18 03:05:28 +00:00
6b38f0d520 Comments and other minor things 2010-08-17 17:52:33 +00:00
0105bb360a Cleanup 2010-08-17 17:47:54 +00:00
35d22a9638 * Fix: EmailPacketFolder.storeAndCreateDeleteRequest() does not correctly handle multiple deletion records in the same DEL_ file
* Fix: Delete verification hash contains the same data as the delete auth key. Apply SHA256 so the delete verification hash actually is the hash of the auth key.
2010-08-17 17:41:25 +00:00
2cce8c9a7a Remove option to set the UI language, always use the router console setting. The language option was changing the router console language, so it was kind of pointless. 2010-08-16 19:44:13 +00:00
a525c3d920 * Rewrite of MultipartFilter: Use javax.mail.internet.MimeMultipart for multipart parsing, get rid of commons-io and commons-fileupload.
* Move attachment adding code in SendEmailTag.java to Email.java
* Encode attachments in 8bit rather than base64 because base64 negates compression
2010-08-16 08:41:37 +00:00
8f090fd3e3 Clean up test folder when finished 2010-08-12 06:10:49 +00:00
c36b24bad6 * Comments, Formatting
* Move ProxyRequest.java into the seedless package because it is only used there
2010-08-12 06:08:31 +00:00
9b8fd8e6fc * Store metadata files along with email files
* Move the new/old flag to metadata (no more N_ and O_ filename prefixes)
* Write the received time to metadata when an email is received
* Use the received time as the sort criteria when an email has no sent time
2010-08-12 05:46:56 +00:00
078f0952ef Fix an NPE when trying to connect before Seedless is initialized 2010-08-01 06:21:11 +00:00
834331903e * Don't set the Date header if it is already there
* Slight code simplification
2010-08-01 06:18:55 +00:00
b112ad89f3 * Remove KademliaDHTTest (would have been to complicated to implement)
* Add KBucketTest (does nothing yet)
2010-08-01 01:26:12 +00:00
73f8295c9c A few little things 2010-08-01 01:23:25 +00:00
c2da679543 * Make getFilenames() protected
* Remove individualPackets() override in DeletionAwareDhtFolder which does nothing
2010-08-01 01:21:27 +00:00
ac46459a0d Send a specific delay time in relay packets, not a min/max range 2010-08-01 01:16:37 +00:00
c663415ebc Add includeSendTime parameter so Email.updateHeaders() doesn't have to call I2PBote.getInstance(). It also has the small benefit of the "include send time" setting being determined at the time the user clicks Send rather than the time the email is sent from the outbox (which doesn't always happen instantly, for example when there is no network connection yet or several emails are queued in the outbox). 2010-08-01 01:08:38 +00:00
68f9360f40 Folder.iterator(): Don't return null if an invalid/unreadable file is encountered, skip it instead 2010-08-01 00:43:45 +00:00
e0436d1e43 * Do not exit background threads on unchecked exceptions
* I2PBote.java: put all background threads in a Collection like sponge suggested
* Do automatic and user-initiated email checking in one class (EmailChecker)
* New interface NetworkStatusSource, used by OutboxProcessor and EmailChecker
* Several other changes
2010-08-01 00:20:52 +00:00
a488294bb3 Convert tabs to spaces 2010-07-29 00:29:50 +00:00
175345dfe4 Shut down EmailPacketTask threads when the tasks are finished 2010-07-25 05:09:12 +00:00
78bb4f7366 Fix member field name in comment 2010-07-24 07:50:08 +00:00
29f485f4e2 Fix: Reachability of relay peers changes to 100% after startup 2010-07-24 07:47:58 +00:00
b794aaf0e0 Remove unused methods 2010-07-24 02:17:22 +00:00
465d509bcc * Autorefresh "inbox" and "sent" folders
* Autorefresh outbox if it is not empty
2010-07-19 05:39:51 +00:00
a4b25f0ae8 Stop refreshing when the CONNECTED or ERROR status is reached 2010-07-19 01:26:26 +00:00
7feba2f15e * Don't disable the "new email" button
* Refresh the frame until the Check Mail button becomes ungreyed
2010-07-19 01:22:20 +00:00
2e72fb7f36 Don't send email if no recipient, show error message instead 2010-07-18 05:48:17 +00:00
a225fa20b1 Fix NPE when sending before connected 2010-07-18 05:47:22 +00:00
f87fe26811 javadoc Ant target, javadoc formatting, documentation 2010-07-17 22:52:24 +00:00
d2b38a3f33 merge of '34a49b587bbb0c309e60a1df7a9a792654e48fd2'
and 'bf83f8762c1d6cfaa71871d32bdc9a3e089058c1'
2010-07-16 15:41:45 +00:00
ef8a143eb0 Ant build file:
* Use I2P libs from $I2P/lib instead of the mtn working directory
 * More help text
 * Check for presence of the I2P env variable
 * Add "src" to the "all" target
2010-07-16 07:07:48 +00:00
e33d186ed0 When writing a file or creating a directory, set permissions to readable / writable only by owner 2010-07-15 05:20:57 +00:00
0527c1f246 Fix counting of #lines read 2010-07-14 18:46:20 +00:00
7ee570e375 * Translate the string for the outbox status "Queued"
* Remove an unused method
2010-07-14 07:09:14 +00:00
c7182a27cf Remember the selected sender identity when leaving the "new email" page (via the address book button) and returning. 2010-07-14 07:05:57 +00:00
f972c9e2e6 Fix: MultipartFilter drops request parameters that are added via jsp:param in a jsp:forward 2010-07-13 07:52:44 +00:00
29df785ab6 merge of '9c9772d22e302d48a4c849c18c8ff3bcb3ff8404'
and 'e09e454db05d06c660ba0e8e2ff5021aa52ec787'
2010-07-12 06:14:06 +00:00
e3448c9b17 Added needed jar files to project.xml for NB 6.5 2010-07-12 04:29:16 +00:00
a3a8c77963 merge of '3e369acec144cfce4278be9456f6b81de0455791'
and 'dc2bcd3d2bdc8b5c7462377da7462d3f5108b3ee'
2010-07-12 03:48:39 +00:00
67dab8aaf7 merge of '3e369acec144cfce4278be9456f6b81de0455791'
and 'dc2bcd3d2bdc8b5c7462377da7462d3f5108b3ee'
2010-07-12 02:14:52 +00:00
7c2fc47933 Refactor of Seedless:
* Move the doSeedless* methods out of I2PBote.java into the Seedless* classes
 * Move the other Seedless stuff into SeedlessParameters.java
 * Don't inject peers into DHT, call a getter on SeedlessScrapePeers instead
 * Many little things
2010-07-11 23:17:33 +00:00
0a3a2bedf8 Add commons-fileupload-1.2.1.jar and commons-io-1.4.jar to build file 2010-07-11 22:56:17 +00:00
38ab0630af Change announce to 60 minutes to deal with new inter-server transfer specs.
Announces should be done once within 1/5th of it's TTL 72 minutes for bote.
2010-07-11 11:23:41 +00:00
d6be15ca4d * Fix for a bug in the multipart code that broke sending of emails on Jetty
* Ditto for non-ASCII chars not being encoded properly
2010-07-11 00:49:43 +00:00
77ec925d45 Post-merge cleanup. This revision diffs cleanly against 14ada4dcae2f555f4b5539305e32f96bafec675e (the last rev before Seedless). 2010-07-07 05:14:08 +00:00
2bd6eac5af merge of '15679f7110fe5f55407d2d04c63bc18e1d460113'
and '289456e0b294a38c3d0e75d69873d614170f9e58'
2010-07-04 07:42:56 +00:00
50673b6358 Comments 2010-07-04 07:28:05 +00:00
ee578e7b06 Use a SHA256 hash rather than random data for the base32 part of the filename to avoid creating a new copy if a packet is received more than once. 2010-07-04 07:26:14 +00:00
4025734680 * When a relay packet is received, acknowledge receipt to the sender
* Resend relay packets until acknowledgement is received
2010-07-04 07:22:14 +00:00
2bbba38007 * Attachment support
* Lower the priority of some background tasks
2010-07-03 21:59:14 +00:00
479b28f35f Fix: Corrupt padding error with ECDH when the input size is a multiple of 16 2010-06-30 18:36:06 +00:00
07a3340ffa Depend on Seedless _first_, then fallback to built-in, as per HH. 2010-06-28 21:10:51 +00:00
69f289b0d9 Fix annoying NPE 2010-06-25 14:57:59 +00:00
308330c8a0 Success!
We now turn off Seedless peer searches and scrapes when network is connected.
Announce to random ordered Seedless servers.
Thanks to ALL our testers, especially superuser and darrob. 
Thier feedback was very valuable!
2010-06-25 14:50:50 +00:00
aac785dda8 Specify PROTO_DATAGRAM, PORT_UNSPECIFIED, and PORT_UNSPECIFIED when sending.
The default uses PROTO_UNSPECIFIED, which isn't what we wanted.
2010-06-25 13:45:31 +00:00
6bd4cab290 Muxed depends on gzip == true? 2010-06-25 06:49:04 +00:00
816eb59c94 Compress emails before encrypting them 2010-06-25 02:36:15 +00:00
889a28063d * Add sponge as a contributor
* Replace HungryHobo email address with email destination
2010-06-25 02:18:43 +00:00
a783a0ddb8 Salt relay peers like bote does 2010-06-24 22:41:17 +00:00
617122dfe1 Fix NPE. 2010-06-24 20:19:31 +00:00
e471ddd57a Added injection to relay peers as well. This possibly isn't the correct intent. 2010-06-24 20:06:28 +00:00
1999eb2432 merge of '7561cf99368e4a244f4b67c350c0c92f7a1afc08'
and 'a74daea914c9a98d3953dbe4e2507b4ad032ae66'
2010-06-24 17:56:14 +00:00
a22eea0f66 - 2010-06-24 17:55:44 +00:00
62a1a85a8f zap comment 2010-06-24 09:41:21 +00:00
dev
00fbabded2 merge of '5ee8d2f16550b6e4181d9123c069dd8e800059de'
and 'f9c92102d1893e1d6e2597ce50dd617256a4aee3'
2010-06-24 07:46:04 +00:00
dev
53a052382f . 2010-06-24 07:26:58 +00:00
66b970d22b disapproval of revision '0c7dc27eead74ddbe0d89793014d5c1cf2e35b2f' 2010-06-24 06:58:57 +00:00
2b5ce8cf27 And now we hope it is set correctly.
disapproval of revision 'f9c92102d1893e1d6e2597ce50dd617256a4aee3'
2010-06-24 06:26:03 +00:00
408f63bdf9 Hopeful fix to the commits that mtn seems to have goofed up on.
There is nothing in this patch.
2010-06-24 06:24:25 +00:00
1ce75177e9 Change for log debugging. 2010-06-24 06:18:55 +00:00
0df770bc68 Temp fix. See comment KademliaDHT.java ~line 364 2010-06-24 06:12:06 +00:00
120de4af9e Fix stupid bug *embarrassment* 2010-06-24 03:03:50 +00:00
b557973e79 Should work with passworded routerconsole,
Don't know if the injector works right. Needs testing, etc.
That's the part HH needs to finish if it is incorrect.
2010-06-24 03:00:52 +00:00
6b833622cf Seedless:
Can scrape servers
  Can scrape peers
  Can announce
  Can't work with a passworded router console yet.
2010-06-22 18:13:51 +00:00
99baa56af3 Apply patch by zzz to abort the build if <exec> returns non-zero. 2010-06-20 05:20:21 +00:00
95ac52b7ea Increase expiration times in testCheckExpiration() to fix test failures reported by one user. 2010-06-20 05:16:58 +00:00
e4696b2bad Add Netbeans 6.5 Project file 2010-06-18 13:17:50 +00:00
00226dfe4d Remove some unnecessary files from the src target 2010-06-14 08:09:20 +00:00
c0ad846a3d 2010-06-14 07:07:13 +00:00
9a0226674f 0.2.4 2010-06-14 07:06:28 +00:00
5d5a4bc50f Fix "Gateway disabled" error with non-gateway emails 2010-06-14 07:06:06 +00:00
2976f10d92 Don't unnecessarily send a IndexPacketDeleteRequest if there is nothing to delete 2010-06-14 07:00:36 +00:00
9ac0fd128d * Set the X-I2PBote-Sig-Valid header when an email is received
* Use the X-I2PBote-Sig-Valid header flag to determine if an email has a valid signature; only verify the signature if no X-I2PBote-Sig-Valid header
2010-06-14 06:58:45 +00:00
4062cfa97c Restore contents of built-in-peers.txt which I accidentally changed when I moved it to a different package 2010-06-13 07:35:09 +00:00
ff0d6e2ff2 * Change console link name
* Use a b32 update URL
2010-06-13 07:27:34 +00:00
9461bc1edb * Don't use protocol v2 peers as relay peers, put them on the ban list
* Fix: BucketManager doesn't ban unknown peers if they use the wrong protocol
2010-06-13 07:25:15 +00:00
f06e936e10 Update translations and fix a few strings 2010-06-13 07:19:30 +00:00
f90f6059c3 Minor things 2010-06-12 07:40:21 +00:00
f529cd3db0 Gateway (in/outproxy) support 2010-06-12 07:39:37 +00:00
a9a0a5202e Fix sending and displaying of anonymous emails 2010-06-11 20:11:19 +00:00
67a871814e Start peers out at 0 reachability 2010-06-11 20:01:57 +00:00
24d2f2fd9a Suppress two warnings in the ant "compile" target 2010-06-11 07:15:41 +00:00
c3a3a19751 * Include bcprov-ecc-jdk16-145.jar
* Fix path to built-in-peers.txt which has moved
* Don't add jstl.jar and standard jar to the war
2010-06-11 07:12:59 +00:00
37643b15b7 Use 'outbox', not 'outbox/local' for the outbox dir 2010-06-11 02:42:53 +00:00
defbb68445 Make packet type codes compatible to the older packet version so no exceptions are thrown when v0.2.3 peers and v0.2.4 peers try to talk to each other 2010-06-11 02:28:07 +00:00
744c1c1b61 Fix: Existing IndexPackets get lost when adding a new one to the IndexPacketFolder 2010-06-11 02:18:03 +00:00
88e0f5c081 More tests 2010-06-10 18:30:24 +00:00
01eb01dc24 Minor 2010-06-10 08:32:40 +00:00
03dac6db84 Shut down replicateThread when Kademlia shuts down 2010-06-10 08:25:45 +00:00
535dd76c8e * Start / stop the RelayPeerManager service on app startup / shutdown
* Move RelayPeerManager to i2p.bote.service
* Keep reachability statistics on relay peers
2010-06-10 08:24:53 +00:00
e211b1040c Cleanup 2010-06-09 23:22:08 +00:00
8533790aa3 Logging tweak 2010-06-09 20:37:32 +00:00
09a271ba12 Fix NPE when sending email before DHT is done bootstrapping 2010-06-09 20:21:24 +00:00
09337fa259 Minor things 2010-06-09 20:19:40 +00:00
97a93db976 * Fix: Relaying does not work with more than one relay peer
* Add remaining relay-related files
2010-06-09 20:13:49 +00:00
9c9b4b5404 Fix: sentSignal and sentTime were not initialized in one of the CommunicationPacket constructors 2010-06-09 03:11:17 +00:00
9212075b08 Call removePacketListener() even if an exception occurs 2010-06-09 03:08:38 +00:00
0c95890d77 Minor things 2010-06-09 02:48:02 +00:00
135190058a Implement sending of emails through relays 2010-06-09 02:12:13 +00:00
ff87fa0a78 Remove an unused class 2010-06-09 01:34:42 +00:00
ed1b2bcdd2 Start OutboxProcessor and ReplicateThread when Kademlia is finished bootstrapping 2010-06-05 04:51:44 +00:00
6b796c1715 Remove unused constant STALE_THRESHOLD 2010-06-04 06:29:16 +00:00
cdfbd98612 Cleanup 2010-06-04 06:25:58 +00:00
8e471d84a1 Add a paragraph about encryption algorithms to noIdentities.jsp 2010-06-04 06:25:19 +00:00
db72661f57 Implement ECC-256 2010-06-04 06:24:10 +00:00
5524b4b563 Periodically replicate email packets and index packet entries onto other nodes 2010-06-04 06:15:17 +00:00
6488aeac56 Preliminary work for packet replication: Keep a record of (locally) deleted email packets, like it is already the case for index packet entries. Use one common format (the new packet type DeletionInfoPacket) for both packet types so Delete Authorization Keys don't unnecessarily take up space in Index Packets. 2010-05-29 10:05:11 +00:00
91e6daa303 Some minor stuff 2010-05-28 07:12:20 +00:00
f56c3ca1bf Read the Delete Authorization Key from an UnencryptedEmailPacket, not from a received Index Packet (because it's always zeroes) 2010-05-28 07:10:29 +00:00
8c5b402edf * Zero out Delete Authorizations before sending a response to an Index Packet retrieve request
* When an Index Packet Delete Request is received, compare the hash of the Delete Authorization against the local Delete Verification Hash, not the local Delete Authorization (which is always zeros)
2010-05-28 07:04:35 +00:00
50eb754d19 Add license.txt 2010-05-27 03:04:11 +00:00
ae41a90478 Use the AES implementation that comes with I2P instead of a JCE provider because the Sun JRE makes it a PITA to enable "unlimited strength encryption" in an end user friendly manner. Fortunately, only AES is affected by the crypto restrictions.
Another problem with the Sun JRE is that it makes it near impossible to ship only a subset of the 1.7 meg BouncyCastle .jar. The .jar has to be signed with a key certified by Sun, which is a lengthy process that involves giving Sun a DNA sample and sacrificing an animal in front of their headquarters. So the ECC code now uses the BouncyCastle API instead of JCE.
2010-05-27 02:11:58 +00:00
892a795c68 Remove an unused method 2010-05-25 20:50:07 +00:00
d2634bd130 Fix a potential lockup 2010-05-25 20:49:35 +00:00
6a482911b3 Minor stuff 2010-05-25 20:46:18 +00:00
35f1320ef1 Delete email packets and index packet entries that are more than 100 days old 2010-05-25 20:42:48 +00:00
6a9729f898 * Add BouncyCastle ECC library (a subset of bcprov-jdk16-145.jar that only contains the ECDH/ECDSA provider)
* Add BouncyCastle license
2010-05-25 20:14:30 +00:00
a064857ff5 Minor things 2010-05-22 01:48:13 +00:00
3fab712da7 Add null checks 2010-05-22 01:45:47 +00:00
d4542b8449 Add some missing license headers 2010-05-22 01:32:05 +00:00
366fa10ce8 Several changes to the packet format:
* Add time stamps in preparation for packet expiration
 * Change a few packet type codes
 * Support addt'l crypto algorithms, implement elliptic curve encryption
 * Fix two design flaws in the packet format:
    1) anybody can delete index packet entries of others
    2) malicious storage nodes can delete all copies of an email packet before
       the recipient receives the packet
2010-05-22 00:35:46 +00:00
050a6dbbbc 0.2.3 2010-05-10 07:12:57 +00:00
8bb3313f38 Make the INFO log level more useful 2010-05-09 23:24:03 +00:00
e7575018bc Synchronize on packetListeners when iterating 2010-05-09 23:22:21 +00:00
863b58913a Name the "sent" folder something different than the "sent" time column because they translate to different German words. 2010-05-09 09:57:46 +00:00
6d581f37a9 editIdentity.jsp:
* Remove garbage characters at the top of the page
  * Fix the cancel button
2010-05-09 07:58:39 +00:00
8c152f27d8 Delete index packet entries (email packet keys) from the DHT even if all requests for the email packet come back negative. This deals with the problem of index packet entries not going away when the email packet does not exist. 2010-05-09 07:25:44 +00:00
07fdac2312 Some comments 2010-05-09 05:54:25 +00:00
e467e6232a Fix constant s-bucket refreshes when there are very few peers. 2010-05-09 05:46:05 +00:00
6e2a14af39 Override toString() for logging 2010-05-07 07:28:19 +00:00
f23db925ad Move the logStatus() call so it doesn't report alpha-1 parallel requests when there are alpha. 2010-05-07 07:24:52 +00:00
93bf69d0aa Increase alpha to 10 2010-05-07 06:54:34 +00:00
cd74c6aac2 Fix a NPE 2010-05-07 06:35:53 +00:00
240a8c12eb Fix a bug that hides some text if the "ellipsis" CSS class is used.
The fix is to get rid of ellipsis, which was a hack anyway, but it
means no more fade effect when text is cut off.
2010-05-07 06:34:57 +00:00
4888f0dd54 Javascript fix 2010-05-06 18:06:15 +00:00
7c5aa40d26 Increase Kademlia lookup timeout to 5 minutes 2010-05-06 08:16:15 +00:00
d9fb751b7b 2010-05-06 08:14:02 +00:00
a23983f686 Eliminate duplicate message IDs, they cause msgmerge to fail 2010-05-06 08:11:29 +00:00
561b4244d6 Rename activeSince to firstSeen 2010-05-06 05:04:07 +00:00
331f72ef67 2010-05-05 22:49:54 +00:00
bea47a0c5d Remove some dead code 2010-05-05 13:28:12 +00:00
232e6f72e7 Remove the localDestination parameter from the KademliaDHT constructor, read localDestination from the I2PSendQueue instead. 2010-05-05 13:26:55 +00:00
1557694beb * Handle requests to the local destination directly, not through the network
* Fix/add some comments
* Rename CheckEmailTask.findEmailPacketKeys() to CheckEmailTask.getEmailPacketKeys(), rename the parameter to dhtPackets
* Add some debug output
2010-05-05 12:56:12 +00:00
1824e0ddcc 2010-05-05 12:42:55 +00:00
d6d0756a6b Use a bean property for displaying the local destination hash, no need for a tag. 2010-05-05 12:20:38 +00:00
c08eff08db Remove an unused method 2010-05-04 22:31:22 +00:00
7664dcbd5b 2010-05-04 17:30:00 +00:00
1e666ca7de Refresh folder list every 20 seconds when sending, otherwise every 2 minutes 2010-05-04 02:10:48 +00:00
56baffba77 BootstrapTask: unlock bootstrap node before adding to bucket 2010-05-03 21:35:49 +00:00
529b39efe9 Cache message IDs of emails that have been received, and ignore email packets whose message ID is in the cache. 2010-05-03 05:39:54 +00:00
a826750254 When new email arrives, don't do a page refresh, but go to the inbox URL 2010-05-02 03:19:49 +00:00
cff2752b8f Insert a random number into the request string so others can't see contacts or identities using the CSS history hack 2010-05-01 23:11:33 +00:00
3daa866b10 Strip local address book names before sending an email 2010-05-01 21:46:53 +00:00
e1e1a7a8e4 Don't throw a NPE in the call to log.error() 2010-05-01 21:23:03 +00:00
b76288e944 One more trash folder related commit in addition to rev. ec310a306f43f2b5e51f77640f415bca08e5971d 2010-05-01 21:19:20 +00:00
905f9aa974 * Implement the trash folder
* Move emails to trash instead of deleting them; do delete emails from the trash folder
2010-04-30 06:18:21 +00:00
57a2d2b891 * Implement the "Sent" folder
* After an email has been sent, move it to the "Sent" folder
2010-04-29 10:04:05 +00:00
7d060c495a Make the folders box an iframe, auto-refresh if outbox contains emails. 2010-04-29 09:58:24 +00:00
e2c83d58da Add a file I missed in rev. 82ebf22a7ebcec38ddaff619afe27a8e19dc9fcc 2010-04-28 06:33:25 +00:00
f5a73349fb Instead of a random DHT key, use a SHA-256 hash so receivers can verify the integrity of email packets. 2010-04-28 03:26:32 +00:00
f02148e159 Show any recipient, not a local recipient, in the "To" column in the outbox (usually there are no local recipients in an outgoing email). 2010-04-27 05:22:35 +00:00
e03a6640fb Make the "To:" column sortable 2010-04-27 05:04:26 +00:00
a4c37841ec When sorting a folder by address, sort by displayed address, not by header value. 2010-04-27 03:45:42 +00:00
b44f67011f Fix duplicate "identity created" message when creating a new identity 2010-04-26 05:39:06 +00:00
a5765a5920 Remove the "new" parameter which does nothing 2010-04-26 05:34:33 +00:00
ae7c0947cf Fix page title 2010-04-26 05:33:32 +00:00
af9e46c983 Focus the destination field if it is empty; if it is not, focus the name field 2010-04-26 05:01:01 +00:00
eb39dfdb90 Always put a blank recipient field at the end 2010-04-26 04:44:28 +00:00
6b5ad92ea6 Rename Field to EmailAttribute 2010-04-26 04:23:02 +00:00
d60f26561a Escape HTML in the textarea 2010-04-25 23:47:28 +00:00
f36d0f2298 Implement the "remove recipient" button 2010-04-25 23:03:06 +00:00
c796311c55 Replace some JSP code in newEmail.jsp with Java code (it was getting too complex for JSP) 2010-04-25 21:40:03 +00:00
4ee42e9a1f Show the "add to address book" button only for the last address 2010-04-25 05:44:27 +00:00
33ce63db4e * newEmail.jsp: Implement the "add recipient" button
* Rename the JSP function getRecipients to getSortedRecipientParams
* newEmail.jsp: Remove redundant filtering of recipient* parameters which is already done in getSortedRecipientParams()
* sendEmail.jsp: Keep ordering of recipients the same as in the UI
2010-04-25 04:36:47 +00:00
340d6cd83b Handle single quotes and double quotes in text fields 2010-04-24 07:30:56 +00:00
560f6e4946 2010-04-23 06:00:26 +00:00
6445dd5d4c Handle whitespace in email destinations 2010-04-23 04:23:22 +00:00
86fe700d9f When displaying an email, show full Email Destinations only on mouse over 2010-04-22 07:21:59 +00:00
d2d4031f2e Update outbox status after every sendToOne call 2010-04-21 06:29:20 +00:00
e598b81600 Handle CC and BCC addresses 2010-04-21 06:27:38 +00:00
7f9f55fbac Fix title of the outbox page; remove reference to non-existant param.path parameter 2010-04-21 06:23:00 +00:00
a707f2830b After deleting an email, go to the containing folder instead of the inbox. 2010-04-20 20:49:27 +00:00
0f95825828 Save outgoing emails to the outbox and send them in the background 2010-04-20 20:48:29 +00:00
c764008170 More detailed debug output 2010-04-19 02:11:31 +00:00
dc43492537 * If an email destination in an email is known, always show the name from the address book or the identity
* Don't show an add button if sender is a local identity
* Several minor things
2010-04-19 01:48:33 +00:00
e87a4efe2f Default to descending sort order for dates, ascending for all other fields 2010-04-15 05:49:17 +00:00
95cfab5e71 Remove an unused constant 2010-04-15 05:45:27 +00:00
ab1ad92278 * New Email page: Add a button which adds a recipient to the address book
* Address book: In select mode, show a "return" button instead of the "add" button if the address book is empty.
* Rename the HTTP request parameter "search" to "select"
* Fix some JSP compile warnings caused by invalid XML in i2pbote.tld
2010-04-15 03:21:48 +00:00
f2afa866f9 Some comments 2010-04-15 02:25:19 +00:00
de53a1fbc9 Add missing license headers 2010-04-15 02:13:19 +00:00
97f078721b Say whether the unit tests passed or failed 2010-04-11 08:27:52 +00:00
52f295396c Show mail folders sorted; clickable column headers for sorting 2010-04-11 08:23:57 +00:00
ade9804ae6 Remove unnecessary call to getProperty() 2010-04-04 08:04:57 +00:00
7fb9cb8290 * JspStrings.java is the new jsp2po.sh
* Extract strings from <ib:message> tag bodies
* Add a few more missing translations
* Don't translate "value" parameters in <button> tags
* Finish the text in noIdentities.jsp
2010-04-04 08:03:33 +00:00
3d262db251 Fix high CPU usage bug introduced in rev. 54d0f214f9894b433925bc2d0979c5ea6eb924b6,
reported at http://forum.i2p/viewtopic.php?p=23465#23465 (Thanks to the reporter!)
2010-04-03 08:20:43 +00:00
d093f81e46 * Folder.jsp: Add "Unknown Sender" and "Signature" columns
* showEmail.jsp: Show whether the signature is valid
2010-04-01 06:49:25 +00:00
1c2af589fd Oops, forgot to add Locales.java in rev. 9b93a31813555d2157e6a815e907bb3f6b5c31fe 2010-03-31 07:57:26 +00:00
daa289bed1 Add EmailTest.java 2010-03-31 07:54:34 +00:00
40ad4cd488 Fix a NPE 2010-03-31 07:51:43 +00:00
d9931f519d * Sign outgoing emails, verify signatures of incoming emails
* Don't make a copy of the email for removing BCC headers, work on the original
* Remove unused methods from i2p.bote.Util
2010-03-31 07:47:31 +00:00
78a5d59ef3 * Fix: i2pbote-update.xpi2p too big when building the plugin target twice in a row
* Add missing files to the src target
2010-03-29 23:58:23 +00:00
c4be1543ce A few minor things 2010-03-29 05:31:05 +00:00
2652d75346 Don't query locked peers 2010-03-29 05:30:18 +00:00
72621a20c9 * Add a UI option to include / not include the "sent" time when sending an email
* Format the "active since" column on network.jsp according to the locale
2010-03-29 05:28:20 +00:00
960f480d3a Remove extra line in the <textarea> 2010-03-28 06:18:08 +00:00
d8f7d8bfb2 * Show "sent" date/time in showEmail.jsp
* Format date/time according to locale
2010-03-28 04:10:45 +00:00
4b0fdf6932 * Alternate colors in folder list
* Replace tabs with spaces in folder.jsp
2010-03-27 21:13:55 +00:00
739e517c3f Do not translate the directory name in a folder link, only the display name 2010-03-27 20:52:45 +00:00
0af131b043 * Make language user-configurable
* Optionally leave text that is auto-added to an email, such as "Re:", untranslated
2010-03-27 04:21:54 +00:00
b780f79e30 * Move setLastLookupTime() calls from KademliaDHT to BucketManager
* More logging changes
2010-03-25 03:47:31 +00:00
6fcaf3761c Synchronize on pendingRequests in packetReceived 2010-03-25 03:17:55 +00:00
9bf0f45ad0 2010-03-23 19:41:03 +00:00
d23ac867a4 Add/change log output, add some comments 2010-03-23 19:34:50 +00:00
3195fd1cb3 2010-03-23 19:00:56 +00:00
515 changed files with 89298 additions and 9912 deletions

69
.mtn-ignore Normal file
View 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
View 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
View 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
View 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

Binary file not shown.

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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} &lt;${contact.destination}&gt;"/>
</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"/>

View File

@ -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=&quot;disabled&quot;"/>
</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=&quot;_parent&quot;"/>
</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>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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>

View File

@ -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: '...';
}

View File

@ -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"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -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>

View File

@ -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} &lt;${identity.key}&gt;"${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"/>

View File

@ -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"/>

View File

@ -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>

View File

@ -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"/>

View File

@ -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=&quot; disabled&quot; title=&quot;The Email Destination already exists in the address book.&quot;'}"/>
<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"/>

View File

@ -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>

View File

@ -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
View File

@ -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="&lt;!-- precompiled servlets --&gt;" 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="&lt;/packs&gt;"/>
<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

Binary file not shown.

BIN
doc/manual_fr.odt Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

BIN
lib/jcommon-1.0.23.jar Normal file

Binary file not shown.

BIN
lib/jfreechart-1.0.19.jar Normal file

Binary file not shown.

BIN
lib/lzma-9.20.jar Normal file

Binary file not shown.

BIN
lib/ntruenc-1.2.jar Normal file

Binary file not shown.

BIN
lib/scrypt-1.4.0.jar Normal file

Binary file not shown.

View File

@ -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
View 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
View 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>.

View 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

File diff suppressed because it is too large Load Diff

1332
locale/messages_cs.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1356
locale/messages_en.po Normal file

File diff suppressed because it is too large Load Diff

1392
locale/messages_es.po Normal file

File diff suppressed because it is too large Load Diff

1317
locale/messages_fi.po Normal file

File diff suppressed because it is too large Load Diff

1378
locale/messages_fr.po Normal file

File diff suppressed because it is too large Load Diff

1332
locale/messages_hu.po Normal file

File diff suppressed because it is too large Load Diff

1352
locale/messages_id.po Normal file

File diff suppressed because it is too large Load Diff

1369
locale/messages_it.po Normal file

File diff suppressed because it is too large Load Diff

1343
locale/messages_ja.po Normal file

File diff suppressed because it is too large Load Diff

1347
locale/messages_nb.po Normal file

File diff suppressed because it is too large Load Diff

1366
locale/messages_nl.po Normal file

File diff suppressed because it is too large Load Diff

1363
locale/messages_pl.po Normal file

File diff suppressed because it is too large Load Diff

1366
locale/messages_pt.po Normal file

File diff suppressed because it is too large Load Diff

1339
locale/messages_pt_BR.po Normal file

File diff suppressed because it is too large Load Diff

1356
locale/messages_ro.po Normal file

File diff suppressed because it is too large Load Diff

1367
locale/messages_ru.po Normal file

File diff suppressed because it is too large Load Diff

1353
locale/messages_sk.po Normal file

File diff suppressed because it is too large Load Diff

1357
locale/messages_sv.po Normal file

File diff suppressed because it is too large Load Diff

1326
locale/messages_uk.po Normal file

File diff suppressed because it is too large Load Diff

1325
locale/messages_vi.po Normal file

File diff suppressed because it is too large Load Diff

1335
locale/messages_zh.po Normal file

File diff suppressed because it is too large Load Diff

113
nbproject/project.xml Normal file
View 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>

View File

@ -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

View File

@ -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

View 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 &lt;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 &lt;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;
}
}
}

View File

@ -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());
}
}

View 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();
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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() + ">";
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -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;
}

Some files were not shown because too many files have changed in this diff Show More