Search code examples
ccurlgmaillibcurlsmtps

cURL terminal command executes successfully while libcurl program doesn't


#include <curl/curl.h>

int main(int argc, char *argv[])
{
  CURLcode ret;
  CURL *hnd;
  struct curl_slist *slist1;

  slist1 = NULL;
  slist1 = curl_slist_append(slist1, "[email protected]");

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, (curl_off_t)179);
  curl_easy_setopt(hnd, CURLOPT_URL, "smtps://smtp.gmail.com:465/mail.txt");
  curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt(hnd, CURLOPT_USERPWD, "[email protected]:senderPass");
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.47.0");
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
  curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
  curl_easy_setopt(hnd, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
  curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "[email protected]");
  curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1);
  curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;
  curl_slist_free_all(slist1);
  slist1 = NULL;

  return (int)ret;
}

The above libcurl code was generated by command line with the following command:

curl --url 'smtps://smtp.gmail.com:465' --ssl-reqd --mail-from '[email protected]' --mail-rcpt '[email protected]' --upload-file mail.txt --user '[email protected]:senderPass' --insecure --libcurl -myCode.c

The command

curl --url 'smtps://smtp.gmail.com:465' --ssl-reqd --mail-from '[email protected]' --mail-rcpt '[email protected]' --upload-file mail.txt --user '[email protected]:senderPass' --insecure

successfully sends the mail; so I was wondering why could myCode.c be failing to send the mail. Output of the verbose option stops responding after

< 354 Go ahead [somecharacters].43 -gsmtp

and the mail.txt file is:

From: "I am Sender" <[email protected]>
To: "I am Receiver" <[email protected]>
Subject: This is a test

Hi,
I’m sending this mail with curl through my gmail account.
Bye!

Solution

  • You have to specify the file descriptor of the file to read from with CURLOPT_READDATA :

    curl_easy_setopt(hnd, CURLOPT_READDATA, fd);
    

    The whole code would look like :

    #include <curl/curl.h>
    
    int main(int argc, char *argv[])
    {
        CURLcode ret;
        CURL *hnd;
        struct curl_slist *slist1;
    
        slist1 = NULL;
        slist1 = curl_slist_append(slist1, "[email protected]");
    
        FILE *fd;
    
        fd = fopen("mail.txt", "rb");
    
        if(!fd)
            return 1; 
    
        hnd = curl_easy_init();
        curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, (curl_off_t)179);
        curl_easy_setopt(hnd, CURLOPT_URL, "smtps://smtp.gmail.com:465/mail.txt");
        curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
    
        curl_easy_setopt(hnd, CURLOPT_READDATA, fd); 
    
        curl_easy_setopt(hnd, CURLOPT_USERPWD, "[email protected]:senderPass");
        curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.47.0");
        curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(hnd, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
        curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
        curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "[email protected]");
        curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1);
        curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
    
        ret = curl_easy_perform(hnd);
    
        curl_easy_cleanup(hnd);
        hnd = NULL;
        curl_slist_free_all(slist1);
        slist1 = NULL;
    
        return (int)ret;
    }