title: Mail format via C socket programming
body: <p>I am learning socket programming in C and the best way to learn something is by implementing it. So I wrote a simple program to send mail with an attachment and some text body via C Socket Programming. The code is by far successfully with only one exception - formatting. MIME headers are showing up in mail body (screenshot attached) and mail subject is all messed up.</p>
  
  <pre><code>#ifndef WIN32_LEAN_AND_MEAN
  #define WIN32_LEAN_AND_MEAN
  #endif
  
  #include &lt;windows.h&gt;
  #include &lt;winsock2.h&gt;
  #include &lt;ws2tcpip.h&gt;
  #include &lt;iphlpapi.h&gt;
  #include &lt;stdio.h&gt;
  
  #pragma comment(lib, "Ws2_32.lib")
  
  #define SMTP_PORT "25"
  #define DEFAULT_BUFLEN 1024
  
  int sendData(SOCKET* socket, const char* data)
  {
      int iResult;
      printf("%s", data);
      iResult = send(*socket, data, (int)strlen(data), 0);
      if (iResult == SOCKET_ERROR) {
          printf("send failed (msg: %s): %d\n", data, WSAGetLastError());
      }
      return iResult;
  }
  
  void recvData(SOCKET* socket)
  {
      int recvbuflen = DEFAULT_BUFLEN;
      char recvbuf[DEFAULT_BUFLEN];
      int iResult;
      iResult = recv(*socket, recvbuf, recvbuflen - 1, 0);
      printf("In recvData function: %d\n", iResult);
      if (iResult &gt; 0) {
          recvbuf[iResult] = '\0';
          printf("%s", recvbuf);
      }
      else if (iResult == 0)
          printf("Connection closed\n");
      else
          printf("recv failed: %d\n", WSAGetLastError());
  }
  
  int main(int argc, char** argv)
  {
      WSADATA wsaData;
  
      int iResult;
      iResult = WSAStartup(MAKEWORD(2, 2), &amp;wsaData);
      if (iResult != 0) {
          printf("WSAStartup failed: %d\n", iResult);
          return 1;
      }
  
      struct addrinfo *result = NULL;
      struct addrinfo *ptr = NULL;
      struct addrinfo hints;
  
      ZeroMemory(&amp;hints, sizeof(hints));
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
  
      iResult = getaddrinfo("mail.sharklasers.com", SMTP_PORT, &amp;hints, &amp;result);
      if (iResult != 0) {
          printf("getaddrinfo failed: %d\n", iResult);
          WSACleanup();
          return 1;
      }
  
      SOCKET ConnectSocket = INVALID_SOCKET;
      for (ptr = result; ptr != NULL; ptr = ptr-&gt;ai_next) {
          ConnectSocket = socket(ptr-&gt;ai_family, ptr-&gt;ai_socktype, ptr-&gt;ai_protocol);
          if (ConnectSocket == INVALID_SOCKET) {
              printf("socket failed: %ld\n", WSAGetLastError());
              WSACleanup();
              return 1;
          }
  
          iResult = connect(ConnectSocket, ptr-&gt;ai_addr, (int)ptr-&gt;ai_addrlen);
          if (iResult == SOCKET_ERROR) {
              closesocket(ConnectSocket);
              ConnectSocket = INVALID_SOCKET;
              continue;
          }
          break;
      }
      freeaddrinfo(result);
  
      if (ConnectSocket == INVALID_SOCKET) {
          printf("Unable to connect to server!\n");
          WSACleanup();
          return 1;
      }
  
      sendData(&amp;ConnectSocket, "HELO mail.sharklasers.com\r\n");
      recvData(&amp;ConnectSocket);
      sendData(&amp;ConnectSocket, "MAIL FROM: psgibrxp@sharklasers.com\r\n");
      recvData(&amp;ConnectSocket);
      sendData(&amp;ConnectSocket, "RCPT TO: psgibrxp@sharklasers.com\r\n");
      recvData(&amp;ConnectSocket);
      sendData(&amp;ConnectSocket, "DATA\r\n");
      recvData(&amp;ConnectSocket);
      sendData(&amp;ConnectSocket, "Subject:This is subject of my mail\r\n");
      sendData(&amp;ConnectSocket, "And this is text\r\n");
      sendData(&amp;ConnectSocket, "MIME-Version: 1.0\r\n");
      sendData(&amp;ConnectSocket, "Content-Type:multipart/mixed;boundary=\"KkK170891tpbkKk__FV_KKKkkkjjwq\"\r\n");
      sendData(&amp;ConnectSocket, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n");
      sendData(&amp;ConnectSocket, "Content-Transfer-Encoding: quoted-printable\r\n");
      sendData(&amp;ConnectSocket, "Content-Type: text/plain;name=\"details.txt\"\r\n");
      sendData(&amp;ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n");
      sendData(&amp;ConnectSocket, "\r\n\r\n");
  
      FILE* MailFilePtr = fopen("details.txt", "r");
      if (MailFilePtr == NULL)
          printf("Error opening attachment\n");
  
      char FileBuffer[1024];
      char buf[1024];
  
      memset(FileBuffer, 0, sizeof(FileBuffer));
      while (fgets(FileBuffer, sizeof(FileBuffer), MailFilePtr))
      {
          sprintf(buf, "%s", FileBuffer);
          buf[strlen(buf) - 1] = 0;
          sendData(&amp;ConnectSocket, buf);
          memset(FileBuffer, 0, sizeof(FileBuffer));
          memset(buf, 0, sizeof(buf));
      }
  
      fclose(MailFilePtr);
  
      sendData(&amp;ConnectSocket, "\r\n\r\n--KkK170891tpbkKk__FV_KKKkkkjjwq--\r\n\r\n");
      sendData(&amp;ConnectSocket, ".\r\n");
      recvData(&amp;ConnectSocket);
  
      sendData(&amp;ConnectSocket, "QUIT\r\n");
  
      iResult = shutdown(ConnectSocket, SD_SEND);
      if (iResult == SOCKET_ERROR) {
          printf("shutdown failed: %d\n", WSAGetLastError());
          closesocket(ConnectSocket);
          WSACleanup();
          return 1;
      }
  
      closesocket(ConnectSocket);
      WSACleanup();
      return 0;
  }
  </code></pre>
  
  <p><strong>Question:</strong>
  How can I get mail body in proper format? I think I am missing some SMTP command or command sequence, but I am not sure.</p>
  
  <p><strong>NOTE</strong></p>
  
  <ol>
  <li>I am using Guerrilla Mail for now, as Gmail needs SSL\TLS is required for communication (correct me if I am wrong). I will use openssl library for that.</li>
  <li>This is not the final code. I do have to do some code clean up. However, code review suggestions are also welcome.</li>
  <li>I am here to learn, so any links, book reference related to C Language and Network Programming are welcome.</li>
  </ol>
  
  <p><strong>EDIT</strong></p>
  
  <p>Edited code is based on comments and answers so far. Unfortunately the problem still exist.
  Instead of reading the file, i am directly passing the base64 encoded attachment (this is working). The output of this edited code is show below in screenshot</p>
  
  <pre><code>    sendData(&amp;ConnectSocket, "MIME-Version: 1.0\r\n");
      sendData(&amp;ConnectSocket, "Content-Type:multipart/mixed;boundary=\"977d81ff9d852ab2a0cad646f8058349\"\r\n");
      sendData(&amp;ConnectSocket, "Subject:This is subject of my mail\r\n");
      sendData(&amp;ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
      sendData(&amp;ConnectSocket, "Content-Type: text/plain; charset=\"utf-8\"\r\n");
      sendData(&amp;ConnectSocket, "Content-Transfer-Encoding: quoted-printable\r\n\r\n");
      sendData(&amp;ConnectSocket, "Hi Me,=0A=0AThis is an empty file.=0A=0ARegards,=0A&lt;ME&gt;=0A=0A---- =0ASent using Guerrillamail.com =0ABlock or report abuse : https://www.guerrillamail.com//abuse/?a=3DUVJzDA8SW6Q1mwa14nUTcwfCX9ne0dhd=0A \r\n\r\n");
      sendData(&amp;ConnectSocket, "--977d81ff9d852ab2a0cad646f8058349\r\n");
      sendData(&amp;ConnectSocket, "Content-Type: text/plain\r\n");
      sendData(&amp;ConnectSocket, "Content-Transfer-Encoding: base64\r\n");
      sendData(&amp;ConnectSocket, "Content-Disposition: attachment; filename=\"details.txt\"\r\n\r\n");
      sendData(&amp;ConnectSocket, "U2FtcGxlIFRleHQu");
      sendData(&amp;ConnectSocket, "\r\n\r\n--977d81ff9d852ab2a0cad646f8058349--\r\n\r\n");
      sendData(&amp;ConnectSocket, ".\r\n");
      recvData(&amp;ConnectSocket);
      sendData(&amp;ConnectSocket, "QUIT\r\n");
  </code></pre>
  
  <p><strong>Edited Output Mail Screenshot:</strong></p>
  
  <p><a href="https://i.stack.imgur.com/HNFNv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HNFNv.png" alt="Output Mail Screenshot"></a></p>