Process BinHex email attachments

One of the recent Mail.dll email component updates brings the ability to process BinHex encoded email attachments.

BinHex is short for “binary-to-hexadecimal”. It is a binary to 7bit ASCII text encoding, that was used on the Mac OS for sending binary files through email. It is similar to Uuencode and Base64 encodings (both supported by Mail.dll), but it combines both “forks” (data and resources) of the Mac file.

As with all other data-to-ASCII encodings, BinHex files usually take more space than the original files, however as BinHex includes very simple run-length compression, encoded files may be smaller under some circumstances.

Below you can see such file inside a MIME entity:

Content-type: application/mac-binhex40; name="binhex.test.sit"
Content-disposition: attachment; filename="binhex.test.sit"

(This file must be converted with BinHex 4.0)

:$f*TEQKPH#jdCA0d,R0TG!"6594%8dP8)3#3"!&m!*!%EMa6593K!!%!!!&mFNa
[...]
Z"`#3!fKi!!!:

Mail.dll is going to extract data fork from such entity and put it in the IMail.Attachments collection, just like it was attached using standard MIME-way.

byte[] eml = ...;

IMail mail = new MailBuilder().CreateFromEml(eml);
Assert.AreEqual(1, mail.Attachments.Count);
MimeData att = (MimeData) mail.Attachments[0];

byte[] data = att.Data; // data fork

You can control, if BinHex attachments should be processed using MailBuilder.ProcessBinHexAutomatically property:

byte[] eml = ...;

MailBuilder builder = new MailBuilder();
builder.ProcessBinHexAutomatically = false;
IMail mail = builder.CreateFromEml(eml);
Assert.AreEqual(1, mail.Attachments.Count);
MimeBinHex binHex = (MimeBinHex) mail.Attachments[0];

byte[] data = binHex.BinHex.Data;
byte[] resource = binHex.BinHex.Resource;

string name = binHex.BinHex.Name;

As you can see, data fork is not extracted automatically and you can use MimeBinHex instance to access both data and resource forks and other information stored inside the BinHex encoded attachment.

Eml is now of byte[] type (Cannot implicitly convert type ‘byte[]’ to ‘string’)

In most recent version of Mail.dll we decided to change how email data is internally stored. This improves both memory usage and raw, not encoded utf-8 data handling. As every major change this leads to a small breaking changes in Mail.dll’s public interface.

In most cases changes required will be very minor. Most common are data type changes from string to byte[] or var keyword.

Below you can find a most common change guidance:

Downloading an email

change:

string eml = client.GetMessageByUID(uid);
IMail email = new MailBuilder().CreateFromEml(eml);

to:

byte[] eml = client.GetMessageByUID(uid);
IMail email = new MailBuilder().CreateFromEml(eml);

Saving an email to a file

change:

string eml = client.GetMessageByUID(uid);
File.WriteAllText(fileName, eml, Encoding.GetEncoding(1252));

to:

byte[] eml = client.GetMessageByUID(uid);
File.WriteAllBytes(fileName, eml);

Reading an email from a file

change:

string eml = File.ReadAllText(fileName, Encoding.GetEncoding(1252));
IMail email = new MailBuilder().CreateFromEml(eml);

to:

byte[] eml = File.ReadAllBytes(fileName);
IMail email = new MailBuilder().CreateFromEml(eml);

Uploading an email read from a file

change:

string eml = File.ReadAllText(fileName, Encoding.GetEncoding(1252));
client.UploadMessage("Inbox", eml);

to:

byte[] eml = File.ReadAllBytes(fileName);
client.UploadMessage("Inbox", eml);

Mail2World IMAP search ALL bug

Another broken IMAP server.


S: * OK Mail2World IMAP4 Server 2.6 64bit ready
S: 76abb5398bc44413 OK CAPABILITY completed
C: 1d5827aea22047ea LOGIN X Y
S: 1d5827aea22047ea OK LOGIN completed
C: b094a8b36bce4d26 EXAMINE "INBOX"
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Recent)
S: * 1 EXISTS
S: * 0 RECENT
S: * OK [PERMANENTFLAGS ()] No permanent flags permitted
S: * OK [UNSEEN 0] first unseen
S: * OK [UIDVALIDITY 42389] UIDs are valid
S: b094a8b36bce4d26 OK [READ-ONLY] opened INBOX
C: 95d4bf743ec949dd UID SEARCH ALL
S: 95d4bf743ec949dd BAD UID SEARCH wrong arguments passed.

“UID SEARCH ALL” is a valid IMAP search query, all servers I know (e.g. Gmail, Exchange) support it without any problems. I can’t imagine a simpler search query, than “UID SEARCH ALL”.

I doubt any email program can download anything from this server.

Funny enough such broken commands as: “UID SEARCH 1:* UID” or “UID SEARCH ALL UID” work on this server.

Nevertheless latest version of Mail.dll is smart enough to access this server.

NavigateToTest VS2013 extension

You can download the extension here:
NavigateToTest Visual Studio 2013 extension

Here’s the latest version that supports Visual Studio 2013.

Extension is convention based. It matches ClassName file with ClassNameTest or ClassNameTests and vice-versa, so you can easily navigate to the test file and back.

Here are some screenshots:

Here’s the toolbar and two opened files:

You can download the extension here:
NavigateToTest Visual Studio 2013 extension

Gmail SMTP authentication and STARTTLS bug

Most SMTP servers don’t accept not encrypted connections, or require to secure such connection using explicit SSL.
Usually in such case LOGINDISABLED and STARTTLS are send in response to EHLO command. Some servers send STARTTLS and simply don’t send any AUTH responses.

Recently Gmail started to act differently (and incorrect):

S: 220 mx.google.com ESMTP hc4sm6305585wjc.9 - gsmtp
C: EHLO [192.168.0.11]
S: 250-mx.google.com at your service, [89.67.21.113]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
S: 250-ENHANCEDSTATUSCODES
S: 250 CHUNKING
C: AUTH LOGIN
S: 530 5.7.0 Must issue a STARTTLS command first. hc4sm6305585wjc.9 - gsmtp

Server claims that it accepts LOGIN command:
S: 250-AUTH LOGIN
but when it is send, it claims that you must issue STARTTLS first:
S: 530 5.7.0 Must issue a STARTTLS command first. hc4sm6305585wjc.9 - gsmtp

This doesn’t make much sense and Gmail should not send “250-AUTH LOGIN PLAIN”.