Search code examples
csmtpmime-types

Why is '\r' (CR) is getting appended before '\n' (LF) when a binary file is sent as an attachment using esmtp, C code


I am sending an email from a device. Email has both text and attachment. Below is the MIME headers I am using

     strLen += sprintf(&headerBuf[strLen], "%s\r\n","MIME-Version: 1.0");
     strLen += sprintf(&headerBuf[strLen], "From: %s\r\n", fromEmailAddr);
     strLen += sprintf(&headerBuf[strLen], "To: %s\r\n", toEmailAddr);
     strLen += sprintf(&headerBuf[strLen], "Subject: %s\r\n","PQdiff File");
     strLen += sprintf(&headerBuf[strLen], "%s\r\n","Content-Type:multipart/mixed; boundary=pqdiffdata");
     strLen += sprintf(&headerBuf[strLen], "%s\r\n","--pqdiffdata");
     strLen += sprintf(&headerBuf[strLen], "%s\r\n","Content-Type: text/html;");
     strLen += sprintf(&headerBuf[strLen], "%s\r\n"," charset=iso-8859-1");
     strLen += sprintf(&headerBuf[strLen], "%s\r\n","Content-Transfer-Encoding: 7bit");

     HTML text goes here
<html>
<body>
<table border="0" cellpadding="5" cellspacing="0" style="background-color:white;color:black;font-family:arial,helvetica,sans-serif;">
<tr><td colspan="4" style="padding:5px;background-color:white;color:black;font-size:175%;text-align:center">Text1<br /></td></tr>
                <tr style="text-align:left;font-size:100%;white-space:nowrap;" bgcolor="#DCDCDC""><td>Text </td><td>Text2</td></tr>
                <tr style="text-align:left;font-size:100%;white-space:nowrap;" bgcolor="#FFFFFF"><td>Text3</td><td>Text4</td></tr>
                <tr style="text-align:left;font-size:100%;white-space:nowrap;" bgcolor="#DCDCDC"><td>Text</td><td>Text5</td></tr>
                <tr style="text-align:left;font-size:100%;white-space:nowrap;" bgcolor="#FFFFFF"><td>Date/Time</td><td>Date</td></tr>
</table>
</body>
</html>
     strLen = snprintf(&headerBuf[strLen], sizeof(headerBuf), "%s\r\n","--pqdiffdata");
     strLen += sprintf(&buf[strLen], "%s\r\n","Content-Type: application/octet-stream");
     strLen += sprintf(&buf[strLen], "%s\r\n","Content-Transfer-Encoding: binary");
     strLen += sprintf(&buf[strLen], "Content-Disposition: attachment;\r\n filename=%s\r\n\r\n", pqdifFileName);

     Binary data of attached file goes here

     strLen = snprintf(buf, MAX_DATA_BUF_SIZE, "\r\n--pqdiffdata--\r\n\r\n");
   strLen += sprintf(&buf[strLen], "%s\r\n","Content-Type: application/octet-stream; charset=7bit");
   strLen += sprintf(&buf[strLen], "%s\r\n","Content-Transfer-Encoding: base64");
   strLen += sprintf(&buf[strLen], "Content-Disposition: attachment;\r\n filename=%s\r\n\r\n", pqdifFileName);

I am using esmtp and I am able to send email with binary file attachment. But the issue is "\r" is getting appended before "\n" in the attached file content.

I am opening the file to be attached in "rb" mode and then passing the file pointer to esmtp lib using the below API

smtp_set_messagecb (message, readlinefp_cb, fp);

I have also tried using API smtp_set_message_fp (message, fp);, but it didn't help

When I send the same file attached to an email using outlook to gmail, I receive the file without any changes in it's contents.

Please let me know what am I missing here.

Thanks


Solution

  • The safest thing to do here is to Base64-encode your attachment and render it as 7-bit MIME. Some servers, but not all, support the 8BITMIME extension (RFC6152) meaning your payload here cannot be delivered to non-supporting servers.

    It may be that your library is unable to attach raw binary files in this manner because it's not widely supported.