merge of '9f159df098940fb0feecf6eae0c990c62736bb9c'

and 'ba82e9e4c57bd8d9f567c9252fe7b5815972e370'
This commit is contained in:
zzz
2014-04-18 01:50:14 +00:00
10 changed files with 133 additions and 49 deletions

View File

@@ -113,10 +113,10 @@ public class ConfigClientsHelper extends HelperBase {
renderForm(buf, ""+cur, ca.clientName, renderForm(buf, ""+cur, ca.clientName,
// urlify, enabled // urlify, enabled
false, !ca.disabled, false, !ca.disabled,
// read only // read only, preventDisable
// dangerous, but allow editing the console args too // dangerous, but allow editing the console args too
//"webConsole".equals(ca.clientName) || "Web console".equals(ca.clientName), //"webConsole".equals(ca.clientName) || "Web console".equals(ca.clientName),
false, false, RouterConsoleRunner.class.getName().equals(ca.className),
// description, edit // description, edit
ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit), ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit),
// show edit button, show update button // show edit button, show update button
@@ -129,7 +129,7 @@ public class ConfigClientsHelper extends HelperBase {
} }
if ("new".equals(_edit)) if ("new".equals(_edit))
renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false, false); renderForm(buf, "" + clients.size(), "", false, false, false, false, "", true, false, false, false, false, false);
buf.append("</table>\n"); buf.append("</table>\n");
return buf.toString(); return buf.toString();
} }
@@ -150,7 +150,8 @@ public class ConfigClientsHelper extends HelperBase {
String val = props.getProperty(name); String val = props.getProperty(name);
boolean isRunning = WebAppStarter.isWebAppRunning(app); boolean isRunning = WebAppStarter.isWebAppRunning(app);
renderForm(buf, app, app, !"addressbook".equals(app), renderForm(buf, app, app, !"addressbook".equals(app),
"true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war", "true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app),
RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war",
false, false, false, isRunning, false, !isRunning); false, false, false, isRunning, false, !isRunning);
} }
} }
@@ -239,7 +240,7 @@ public class ConfigClientsHelper extends HelperBase {
enableStop &= PluginStarter.isPluginRunning(app, _context); enableStop &= PluginStarter.isPluginRunning(app, _context);
boolean enableStart = !PluginStarter.isPluginRunning(app, _context); boolean enableStart = !PluginStarter.isPluginRunning(app, _context);
renderForm(buf, app, app, false, renderForm(buf, app, app, false,
"true".equals(val), false, desc.toString(), false, false, "true".equals(val), false, false, desc.toString(), false, false,
updateURL != null, enableStop, true, enableStart); updateURL != null, enableStop, true, enableStart);
} }
} }
@@ -253,7 +254,7 @@ public class ConfigClientsHelper extends HelperBase {
* ro trumps edit and showEditButton * ro trumps edit and showEditButton
*/ */
private void renderForm(StringBuilder buf, String index, String name, boolean urlify, private void renderForm(StringBuilder buf, String index, String name, boolean urlify,
boolean enabled, boolean ro, String desc, boolean edit, boolean enabled, boolean ro, boolean preventDisable, String desc, boolean edit,
boolean showEditButton, boolean showUpdateButton, boolean showStopButton, boolean showEditButton, boolean showUpdateButton, boolean showStopButton,
boolean showDeleteButton, boolean showStartButton) { boolean showDeleteButton, boolean showStartButton) {
String escapeddesc = DataHelper.escapeHTML(desc); String escapeddesc = DataHelper.escapeHTML(desc);
@@ -275,7 +276,7 @@ public class ConfigClientsHelper extends HelperBase {
buf.append("</td><td align=\"center\" width=\"10%\"><input type=\"checkbox\" class=\"optbox\" name=\"").append(index).append(".enabled\" value=\"true\" "); buf.append("</td><td align=\"center\" width=\"10%\"><input type=\"checkbox\" class=\"optbox\" name=\"").append(index).append(".enabled\" value=\"true\" ");
if (enabled) { if (enabled) {
buf.append("checked=\"checked\" "); buf.append("checked=\"checked\" ");
if (ro) if (ro || preventDisable)
buf.append("disabled=\"disabled\" "); buf.append("disabled=\"disabled\" ");
} }
buf.append("></td><td align=\"center\" width=\"15%\">"); buf.append("></td><td align=\"center\" width=\"15%\">");

View File

@@ -13,8 +13,22 @@
<condition property="no.bundle"> <condition property="no.bundle">
<isfalse value="${require.gettext}" /> <isfalse value="${require.gettext}" />
</condition> </condition>
<condition property="depend.available">
<typefound name="depend" />
</condition>
<target name="depend" if="depend.available">
<depend
cache="../../build"
srcdir="./src/src"
destdir="./src/WEB-INF/classes" >
<!-- Depend on classes instead of jars where available -->
<classpath>
<pathelement location="../../core/java/build/obj" />
</classpath>
</depend>
</target>
<target name="compile"> <target name="compile" depends="depend" >
<mkdir dir="./src/WEB-INF/classes" /> <mkdir dir="./src/WEB-INF/classes" />
<javac <javac
srcdir="./src/src" srcdir="./src/src"

View File

@@ -13,7 +13,7 @@
<url-pattern>/susimail</url-pattern> <url-pattern>/susimail</url-pattern>
</servlet-mapping> </servlet-mapping>
<session-config> <session-config>
<session-timeout>15</session-timeout> <session-timeout>1440</session-timeout>
</session-config> </session-config>
<!-- <!--

View File

@@ -68,6 +68,16 @@ public class Config {
return result; return result;
} }
/**
* Don't bother showing a reload config button if this returns false.
* @since 0.9.13
*/
public static boolean hasConfigFile() {
File cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), "susimail.config");
return cfg.exists();
}
/** /**
* *
* *

View File

@@ -37,6 +37,9 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone;
import net.i2p.I2PAppContext;
/** /**
* data structure to hold a single message, mostly used with folder view and sorting * data structure to hold a single message, mostly used with folder view and sorting
@@ -51,8 +54,12 @@ public class Mail {
public int id, size; public int id, size;
public String sender, reply, subject, dateString, public String sender, reply, subject, dateString,
formattedSender, formattedSubject, formattedDate, formattedSender, formattedSubject,
shortSender, shortSubject, quotedDate, uidl; formattedDate, // US Locale, UTC
localFormattedDate, // Current Locale, local time zone
shortSender, shortSubject,
quotedDate, // Current Locale, local time zone, longer format
uidl;
public Date date; public Date date;
public ReadBuffer header, body; public ReadBuffer header, body;
public MailPart part; public MailPart part;
@@ -68,6 +75,7 @@ public class Mail {
formattedSender = unknown; formattedSender = unknown;
formattedSubject = unknown; formattedSubject = unknown;
formattedDate = unknown; formattedDate = unknown;
localFormattedDate = unknown;
shortSender = unknown; shortSender = unknown;
shortSubject = unknown; shortSubject = unknown;
quotedDate = unknown; quotedDate = unknown;
@@ -110,7 +118,7 @@ public class Mail {
for( int i = 0; i < tokens.length; i++ ) { for( int i = 0; i < tokens.length; i++ ) {
if( tokens[i].matches( "^[^@< \t]+@[^> \t]+$" ) ) if( tokens[i].matches( "^[^@< \t]+@[^> \t]+$" ) )
return "<" + tokens[i] + ">"; return "<" + tokens[i] + ">";
if( tokens[i].matches( "^<[^@< \t]+@[^> \t]+>$" ) ) if( tokens[i].matches( "^<[^@< \t]+@[^> \t]+>$" ) )
return tokens[i]; return tokens[i];
} }
@@ -149,7 +157,16 @@ public class Mail {
} }
public void parseHeaders() public void parseHeaders()
{ {
DateFormat dateFormatter = new SimpleDateFormat( Config.getProperty( DATEFORMAT, "mm/dd/yyyy HH:mm:ss" ) ); DateFormat dateFormatter = new SimpleDateFormat("yyyy-mm-dd HH:mm");
DateFormat localDateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
DateFormat longLocalDateFormatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
// the router sets the JVM time zone to UTC but saves the original here so we can get it
String systemTimeZone = I2PAppContext.getGlobalContext().getProperty("i2p.systemTimeZone");
if (systemTimeZone != null) {
TimeZone tz = TimeZone.getTimeZone(systemTimeZone);
localDateFormatter.setTimeZone(tz);
longLocalDateFormatter.setTimeZone(tz);
}
DateFormat mailDateFormatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH ); DateFormat mailDateFormatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH );
error = ""; error = "";
@@ -195,7 +212,9 @@ public class Mail {
try { try {
date = mailDateFormatter.parse( dateString ); date = mailDateFormatter.parse( dateString );
formattedDate = dateFormatter.format( date ); formattedDate = dateFormatter.format( date );
quotedDate = html.encode( dateString ); localFormattedDate = localDateFormatter.format( date );
//quotedDate = html.encode( dateString );
quotedDate = longLocalDateFormatter.format(date);
} }
catch (ParseException e) { catch (ParseException e) {
date = null; date = null;
@@ -211,16 +230,16 @@ public class Mail {
shortSubject = html.encode( shortSubject ); shortSubject = html.encode( shortSubject );
} }
else if( line.toLowerCase(Locale.US).startsWith( "reply-to:" ) ) { else if( line.toLowerCase(Locale.US).startsWith( "reply-to:" ) ) {
reply = Mail.getAddress( line.substring( 9 ).trim() ); reply = getAddress( line.substring( 9 ).trim() );
} }
else if( line.startsWith( "To:" ) ) { else if( line.startsWith( "To:" ) ) {
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
Mail.getRecipientsFromList( list, line.substring( 3 ).trim(), true ); getRecipientsFromList( list, line.substring( 3 ).trim(), true );
to = list.toArray(); to = list.toArray();
} }
else if( line.startsWith( "Cc:" ) ) { else if( line.startsWith( "Cc:" ) ) {
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
Mail.getRecipientsFromList( list, line.substring( 3 ).trim(), true ); getRecipientsFromList( list, line.substring( 3 ).trim(), true );
cc = list.toArray(); cc = list.toArray();
} }
} }

View File

@@ -370,7 +370,9 @@ public class WebMail extends HttpServlet
*/ */
private static String sortHeader( String name, String label, String imgPath ) private static String sortHeader( String name, String label, String imgPath )
{ {
return "" + label + "&nbsp;<a href=\"" + myself + "?" + name + "=up\"><img src=\"" + imgPath + "3up.png\" border=\"0\" alt=\"^\"></a><a href=\"" + myself + "?" + name + "=down\"><img src=\"" + imgPath + "3down.png\" border=\"0\" alt=\"v\"></a>"; return label + "&nbsp;<a href=\"" + myself + "?" + name + "=up\"><img src=\"" +
imgPath + "3up.png\" border=\"0\" alt=\"^\"></a><a href=\"" + myself +
"?" + name + "=down\"><img src=\"" + imgPath + "3down.png\" border=\"0\" alt=\"v\"></a>";
} }
/** /**
* check, if a given button "was pressed" in the received http request * check, if a given button "was pressed" in the received http request
@@ -758,7 +760,7 @@ public class WebMail extends HttpServlet
sessionObject.subject = "Re: " + mail.formattedSubject; sessionObject.subject = "Re: " + mail.formattedSubject;
StringWriter text = new StringWriter(); StringWriter text = new StringWriter();
PrintWriter pw = new PrintWriter( text ); PrintWriter pw = new PrintWriter( text );
pw.println( _("On {0} {1} wrote:", mail.formattedDate, sessionObject.replyTo) ); pw.println( _("On {0} {1} wrote:", mail.formattedDate + " UTC", sessionObject.replyTo) );
StringWriter text2 = new StringWriter(); StringWriter text2 = new StringWriter();
PrintWriter pw2 = new PrintWriter( text2 ); PrintWriter pw2 = new PrintWriter( text2 );
showPart( pw2, mail.part, 0, TEXT_ONLY ); showPart( pw2, mail.part, 0, TEXT_ONLY );
@@ -1273,7 +1275,7 @@ public class WebMail extends HttpServlet
if( sessionObject.state == STATE_LIST ) { if( sessionObject.state == STATE_LIST ) {
processFolderButtons( sessionObject, request ); processFolderButtons( sessionObject, request );
for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) { for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) {
String uidl = (String)it.next(); String uidl = it.next();
Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER ); Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER );
if( mail != null && mail.error.length() > 0 ) { if( mail != null && mail.error.length() > 0 ) {
sessionObject.error += mail.error; sessionObject.error += mail.error;
@@ -1579,9 +1581,10 @@ public class WebMail extends HttpServlet
{ {
out.println( button( SEND, _("Send") ) + out.println( button( SEND, _("Send") ) +
button( CANCEL, _("Cancel") ) + spacer + button( CANCEL, _("Cancel") ) + spacer +
(sessionObject.attachments != null && (!sessionObject.attachments.isEmpty()) ? button( DELETE_ATTACHMENT, _("Delete Attachment") ) : button2( DELETE_ATTACHMENT, _("Delete Attachment") ) ) + spacer + (sessionObject.attachments != null && (!sessionObject.attachments.isEmpty()) ? button( DELETE_ATTACHMENT, _("Delete Attachment") ) : button2( DELETE_ATTACHMENT, _("Delete Attachment") ) ) + spacer);
button( RELOAD, _("Reload Config") ) + spacer + if (Config.hasConfigFile())
button( LOGOUT, _("Logout") ) ); out.println(button( RELOAD, _("Reload Config") ) + spacer);
out.println(button( LOGOUT, _("Logout") ) );
String from = request.getParameter( NEW_FROM ); String from = request.getParameter( NEW_FROM );
String fixed = Config.getProperty( CONFIG_SENDER_FIXED, "true" ); String fixed = Config.getProperty( CONFIG_SENDER_FIXED, "true" );
@@ -1672,18 +1675,21 @@ public class WebMail extends HttpServlet
button( REPLYALL, _("Reply All") ) + button( REPLYALL, _("Reply All") ) +
button( FORWARD, _("Forward") ) + spacer + button( FORWARD, _("Forward") ) + spacer +
button( DELETE, _("Delete") ) + spacer + button( DELETE, _("Delete") ) + spacer +
button( REFRESH, _("Check Mail") ) + spacer + button( REFRESH, _("Check Mail") ) + spacer);
button( RELOAD, _("Reload Config") ) + spacer + if (Config.hasConfigFile())
button( LOGOUT, _("Logout") ) + "<table id=\"mailbox\" cellspacing=\"0\" cellpadding=\"5\">\n" + out.println(button( RELOAD, _("Reload Config") ) + spacer);
out.println(button( LOGOUT, _("Logout") ) + "<table id=\"mailbox\" cellspacing=\"0\" cellpadding=\"5\">\n" +
"<tr><td colspan=\"8\"><hr></td></tr>\n<tr>" + "<tr><td colspan=\"8\"><hr></td></tr>\n<tr>" +
thSpacer + "<th>" + sortHeader( SORT_SENDER, _("Sender"), sessionObject.imgPath ) + "</th>" + thSpacer + "<th>" + sortHeader( SORT_SENDER, _("Sender"), sessionObject.imgPath ) + "</th>" +
thSpacer + "<th>" + sortHeader( SORT_SUBJECT, _("Subject"), sessionObject.imgPath ) + "</th>" + thSpacer + "<th>" + sortHeader( SORT_SUBJECT, _("Subject"), sessionObject.imgPath ) + "</th>" +
thSpacer + "<th>" + sortHeader( SORT_DATE, _("Date"), sessionObject.imgPath ) + sortHeader( SORT_ID, "", sessionObject.imgPath ) + "</th>" + thSpacer + "<th>" + sortHeader( SORT_DATE, _("Date"), sessionObject.imgPath ) +
//sortHeader( SORT_ID, "", sessionObject.imgPath ) +
"</th>" +
thSpacer + "<th>" + sortHeader( SORT_SIZE, _("Size"), sessionObject.imgPath ) + "</th></tr>" ); thSpacer + "<th>" + sortHeader( SORT_SIZE, _("Size"), sessionObject.imgPath ) + "</th></tr>" );
int bg = 0; int bg = 0;
int i = 0; int i = 0;
for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) { for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) {
String uidl = (String)it.next(); String uidl = it.next();
Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER ); Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER );
String link = "<a href=\"" + myself + "?" + SHOW + "=" + i + "\">"; String link = "<a href=\"" + myself + "?" + SHOW + "=" + i + "\">";
@@ -1705,7 +1711,9 @@ public class WebMail extends HttpServlet
", invert=" + sessionObject.invert + ", invert=" + sessionObject.invert +
", clear=" + sessionObject.clear ); ", clear=" + sessionObject.clear );
out.println( "<tr class=\"list" + bg + "\"><td><input type=\"checkbox\" class=\"optbox\" name=\"check" + i + "\" value=\"1\"" + out.println( "<tr class=\"list" + bg + "\"><td><input type=\"checkbox\" class=\"optbox\" name=\"check" + i + "\" value=\"1\"" +
( idChecked ? "checked" : "" ) + ">" + ( RELEASE ? "" : "" + i ) + "</td><td>" + link + mail.shortSender + "</a></td><td>&nbsp;</td><td>" + link + mail.shortSubject + "</a></td><td>&nbsp;</td><td>" + mail.formattedDate + "</td><td>&nbsp;</td><td>" + ngettext("1 Byte", "{0} Bytes", mail.size) + "</td></tr>" ); ( idChecked ? "checked" : "" ) + ">" + ( RELEASE ? "" : "" + i ) + "</td><td>" +
link + mail.shortSender + "</a></td><td>&nbsp;</td><td>" + link + mail.shortSubject + "</a></td><td>&nbsp;</td><td>" +
mail.localFormattedDate + "</td><td>&nbsp;</td><td>" + ngettext("1 Byte", "{0} Bytes", mail.size) + "</td></tr>" );
bg = 1 - bg; bg = 1 - bg;
i++; i++;
} }
@@ -1754,15 +1762,19 @@ public class WebMail extends HttpServlet
button( DELETE, _("Delete") ) + spacer + button( DELETE, _("Delete") ) + spacer +
( sessionObject.folder.isFirstElement( sessionObject.showUIDL ) ? button2( PREV, _("Previous") ) : button( PREV, _("Previous") ) ) + ( sessionObject.folder.isFirstElement( sessionObject.showUIDL ) ? button2( PREV, _("Previous") ) : button( PREV, _("Previous") ) ) +
( sessionObject.folder.isLastElement( sessionObject.showUIDL ) ? button2( NEXT, _("Next") ) : button( NEXT, _("Next") ) ) + spacer + ( sessionObject.folder.isLastElement( sessionObject.showUIDL ) ? button2( NEXT, _("Next") ) : button( NEXT, _("Next") ) ) + spacer +
button( LIST, _("Back to Folder") ) + spacer + button( LIST, _("Back to Folder") ) + spacer);
button( RELOAD, _("Reload Config") ) + spacer + if (Config.hasConfigFile())
button( LOGOUT, _("Logout") ) ); out.println(button( RELOAD, _("Reload Config") ) + spacer);
out.println(button( LOGOUT, _("Logout") ) );
if( mail != null ) { if( mail != null ) {
out.println( "<table cellspacing=\"0\" cellpadding=\"5\">\n" + out.println( "<table cellspacing=\"0\" cellpadding=\"5\">\n" +
"<tr><td colspan=\"2\" align=\"center\"><hr></td></tr>\n" + "<tr><td colspan=\"2\" align=\"center\"><hr></td></tr>\n" +
"<tr class=\"mailhead\"><td align=\"right\">" + _("From:") + "</td><td align=\"left\">" + quoteHTML( mail.formattedSender ) + "</td></tr>\n" + "<tr class=\"mailhead\"><td align=\"right\" valign=\"top\">" + _("From:") +
"<tr class=\"mailhead\"><td align=\"right\">" + _("Date:") + "</td><td align=\"left\">" + mail.quotedDate + "</td></tr>\n" + "</td><td align=\"left\">" + quoteHTML( mail.sender ) + "</td></tr>\n" +
"<tr class=\"mailhead\"><td align=\"right\">" + _("Subject:") + "</td><td align=\"left\">" + quoteHTML( mail.formattedSubject ) + "</td></tr>\n" + "<tr class=\"mailhead\"><td align=\"right\" valign=\"top\">" + _("Date:") +
"</td><td align=\"left\">" + mail.quotedDate + "</td></tr>\n" +
"<tr class=\"mailhead\"><td align=\"right\" valign=\"top\">" + _("Subject:") +
"</td><td align=\"left\">" + quoteHTML( mail.formattedSubject ) + "</td></tr>\n" +
"<tr><td colspan=\"2\" align=\"center\"><hr></td></tr>" ); "<tr><td colspan=\"2\" align=\"center\"><hr></td></tr>" );
if( mail.body != null ) { if( mail.body != null ) {
showPart( out, mail.part, 0, SHOW_HTML ); showPart( out, mail.part, 0, SHOW_HTML );

View File

@@ -23,12 +23,14 @@
*/ */
package i2p.susi.webmail.encoding; package i2p.susi.webmail.encoding;
import i2p.susi.debug.Debug;
import i2p.susi.util.HexTable; import i2p.susi.util.HexTable;
import i2p.susi.util.ReadBuffer; import i2p.susi.util.ReadBuffer;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Locale;
/** /**
* Ref: * Ref:
@@ -170,7 +172,8 @@ public class HeaderLine implements Encoding {
if( length > 0 ) { if( length > 0 ) {
if( in[offset] == '?' ) { if( in[offset] == '?' ) {
// System.err.println( "=? found at " + ( offset -1 ) ); // System.err.println( "=? found at " + ( offset -1 ) );
int f2 = offset + 1; int f1 = offset;
int f2 = f1 + 1;
// FIXME save charset here ticket #508 // FIXME save charset here ticket #508
for( ; f2 < end && in[f2] != '?'; f2++ ); for( ; f2 < end && in[f2] != '?'; f2++ );
if( f2 < end ) { if( f2 < end ) {
@@ -201,18 +204,31 @@ public class HeaderLine implements Encoding {
try { try {
// System.err.println( "decode(" + (f3 + 1) + "," + ( f4 - f3 - 1 ) + ")" ); // System.err.println( "decode(" + (f3 + 1) + "," + ( f4 - f3 - 1 ) + ")" );
tmp = e.decode( in, f3 + 1, f4 - f3 - 1 ); tmp = e.decode( in, f3 + 1, f4 - f3 - 1 );
// FIXME use saved charset here ticket #508 // get charset
for( int j = 0; j < tmp.length; j++ ) { String charset = new String(in, f1 + 1, f2 - f1 - 1, "ISO-8859-1");
byte d = tmp.content[ tmp.offset + j ]; String clc = charset.toLowerCase(Locale.US);
out[written++] = ( d == '_' ? 32 : d ); if (clc.equals("utf-8") || clc.equals("utf8")) {
for( int j = 0; j < tmp.length; j++ ) {
byte d = tmp.content[ tmp.offset + j ];
out[written++] = ( d == '_' ? 32 : d );
}
} else {
// decode string
String decoded = new String(tmp.content, tmp.offset, tmp.length, charset);
// encode string
byte[] utf8 = decoded.getBytes("UTF-8");
for( int j = 0; j < utf8.length; j++ ) {
byte d = utf8[j];
out[written++] = ( d == '_' ? 32 : d );
}
} }
int distance = f4 + 2 - offset; int distance = f4 + 2 - offset;
offset += distance; offset += distance;
length -= distance; length -= distance;
lastCharWasQuoted = true; lastCharWasQuoted = true;
continue; continue;
} } catch (Exception e1) {
catch (Exception e1) { Debug.debug(Debug.ERROR, e1.toString());
} }
} }
} }

View File

@@ -38,19 +38,19 @@ import java.net.Socket;
*/ */
public class SMTPClient { public class SMTPClient {
Socket socket; private Socket socket;
byte buffer[]; private final byte buffer[];
public String error; public String error;
String lastResponse; private String lastResponse;
private static Encoding base64 = null; private static final Encoding base64;
static { static {
base64 = EncodingFactory.getEncoding( "base64" ); base64 = EncodingFactory.getEncoding( "base64" );
} }
public SMTPClient() public SMTPClient()
{ {
socket = null;
buffer = new byte[10240]; buffer = new byte[10240];
error = ""; error = "";
lastResponse = ""; lastResponse = "";

View File

@@ -11,10 +11,10 @@ susimail.fast.start=true
susimail.sender.fixed=true susimail.sender.fixed=true
susimail.sender.domain=mail.i2p susimail.sender.domain=mail.i2p
susimail.pager.pagesize=10 susimail.pager.pagesize=40
susimail.composer.cols=80 susimail.composer.cols=80
susimail.composer.rows=15 susimail.composer.rows=15
susimail.composer.bcc.to.self=true susimail.composer.bcc.to.self=true
susimail.date.format=MM/dd/yyyy HH:mm:ss susimail.date.format=MM/dd/yyyy HH:mm:ss

View File

@@ -1,3 +1,15 @@
2014-04-18 zzz
* configclients: Don't allow console disable
* SusiMail:
- Extend session expiration (ticket #1253)
- Handle non-UTF8 encoding on header lines (ticket #508)
- Display dates in current locale and time zone
- Display sender name on message view
- Remove sort-by-ID buttons
- Hide "reload config" button unless config file is present
- Increase default page size
- Add dependency tracking to build
2014-04-17 zzz 2014-04-17 zzz
* i2psnark: Randomize announce list order and limit size * i2psnark: Randomize announce list order and limit size
* SSU: SessionRequest replay prevention (ticket #1212) * SSU: SessionRequest replay prevention (ticket #1212)