#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

#define FROM    "<dilbertd@spookyinternet.com>"
#define TO      "<nchambers@spookyinternet.com>"

static const char *payload_text[] = {
  "To: " TO "\r\n",
  "From: " FROM "\r\n",
  "Subject: SMTPS Example\r\n",
  "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
  "User-Agent: My eMail Client\r\n",
  "MIME-Version: 1.0\r\n",
  "Content-Type: multipart/mixed;\r\n",
   " boundary=\"------------030203080101020302070708\"\r\n",    
  "\r\nThis is a multi-part message in MIME format.\r\n",
  "--------------030203080101020302070708\r\n",
  "Content-Type: text/plain; charset=utf-8; format=flowed\r\n",
  "Content-Transfer-Encoding: 7bit\r\n",
  "\r\n", /* empty line to divide headers from body, see RFC5322 */
  "The body of the message starts here.\r\n",
  "\r\n",
  "--------------030203080101020302070708\r\n",
  "Content-Type: image/jpeg;\r\n",
  "  filename=\"purple.jpeg\"\r\n",
  "\r\n",
  "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",
  "jv1cR5jGMIbhxOJ2nP6f//Z\r\n",
  "--------------030203080101020302070708--\r\n",
  NULL
};
 
struct upload_status {
  int lines_read;
};
 
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct upload_status *upload_ctx = (struct upload_status *)userp;
  const char *data;
 
  if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
    return 0;
  }
 
  data = payload_text[upload_ctx->lines_read];
 
  if(data) {
    size_t len = strlen(data);
    memcpy(ptr, data, len);
    upload_ctx->lines_read++;
 
    return len;
  }
 
  return 0;
}
 
int main(void)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *recipients = NULL;
  struct upload_status upload_ctx;
 
  upload_ctx.lines_read = 0;
 
  curl = curl_easy_init();
  if(curl) {
    /* This is the URL for your mailserver */ 
    curl_easy_setopt(curl, CURLOPT_URL, "smtp://localhost:25");
 
    /* Note that this option isn't strictly required, omitting it will result
     * in libcurl sending the MAIL FROM command with empty sender data. All
     * autoresponses should have an empty reverse-path, and should be directed
     * to the address in the reverse-path which triggered them. Otherwise,
     * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
     * details.
     */ 
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
 
    /* Add two recipients, in this particular case they correspond to the
     * To: and Cc: addressees in the header, but they could be any kind of
     * recipient. */ 
    recipients = curl_slist_append(recipients, TO);
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
 
    /* We're using a callback function to specify the payload (the headers and
     * body of the message). You could just use the CURLOPT_READDATA option to
     * specify a FILE pointer to read from. */ 
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
    curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
 
    /* Send the message */ 
    res = curl_easy_perform(curl);
 
    /* Check for errors */ 
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
    /* Free the list of recipients */ 
    curl_slist_free_all(recipients);
 
    /* curl won't send the QUIT command until you call cleanup, so you should
     * be able to re-use this connection for additional messages (setting
     * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
     * curl_easy_perform() again. It may not be a good idea to keep the
     * connection open for a very long time though (more than a few minutes
     * may result in the server timing out the connection), and you do want to
     * clean up in the end.
     */ 
    curl_easy_cleanup(curl);
  }
 
  return (int)res;
}
