2015-12-10 32 views
0

我试图通过对libcurl的发送电子邮件,但我似乎无法使它发挥发送电子邮件:通过libcurl中(C)

我的代码是挂在发送序列结束如下:

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 
* Hostname was NOT found in DNS cache 
[New Thread 0x7ffff2bf7700 (LWP 27664)] 
[Thread 0x7ffff2bf7700 (LWP 27664) exited] 
* Trying 2a00:f60::1:22... 
* Connected to smtp.xxxxx.com (2a00:f60::1:22) port 25 (#0) 
< 220 net3-nl-proxy-12.xxxxx.net ESMTP Postfix 
> EHLO barrybackup 
< 250-net3-nl-proxy-12.xxxxx.net 
< 250-PIPELINING 
< 250-SIZE 262144000 
< 250-ETRN 
< 250-STARTTLS 
< 250-ENHANCEDSTATUSCODES 
< 250-8BITMIME 
< 250 DSN 
> STARTTLS 
< 220 2.0.0 Ready to start TLS 
* successfully set certificate verify locations: 
* CAfile: none 
    CApath: /etc/ssl/certs 
* SSL connection using TLSv1.2/DHE-RSA-AES256-GCM-SHA384 
* Server certificate: 
* subject: OU=Domain Control Validated; OU=Hosted by xxxxx Services bv; OU=PositiveSSL; CN=smtp.xxxxx.com 
* start date: 2015-06-23 00:00:00 GMT 
* expire date: 2016-06-27 23:59:59 GMT 
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA 
* SSL certificate verify ok. 
> EHLO barrybackup 
< 250-net3-nl-proxy-12.xxxxx.net 
< 250-PIPELINING 
< 250-SIZE 262144000 
< 250-ETRN 
< 250-AUTH PLAIN LOGIN 
< 250-ENHANCEDSTATUSCODES 
< 250-8BITMIME 
< 250 DSN 
> AUTH LOGIN 
< 334 VXNlcm5hbWU6 
> aW5mb0BjdW1idWNrZXQubmw= 
< 334 UGFzc3dvcmQ6 
> Rmw0cGRyMGwyMDEy 
< 235 2.7.0 Authentication successful 
> MAIL FROM:<[email protected]> 
< 250 2.1.0 Ok 
> RCPT TO:<[email protected]> 
< 250 2.1.5 Ok 
> DATA 
< 354 End data with <CR><LF>.<CR><LF> 

我似乎无法找出任何线索,并完全卡住。

代码:

typedef struct { 
    const char* toEmail; 
    const char* toName; 
    const char* fromEmail; 
    const char* fromName; 
    const char** subject; 
    const char** email; 
    size_t pos; 
} EmailData; 

EmailData* initEmailData(EmailData* data, const char* toEmail,const char* toName,const char* fromEmail, const char* fromName, const char* subject, const char* body) { 

    data->toEmail = toEmail; 
    data->toName = toName; 
    data->fromEmail = fromEmail; 
    data->fromName = fromName; 


    // the added numbers to the length of the string are the pre-computed 
    // lengths of the strings to be concatenated + 1 (for termination char) 
    size_t htmlSize = strlen(body) + 24; 
    char *html = malloc(htmlSize); 
    snprintf(html, htmlSize, "%s%s", body, "\r\n");  

    size_t headerSize = strlen(subject) + 14; 
    char *header = malloc(1); 
    snprintf(header, headerSize, "%s%s%s", "Subject: ", subject, "\r\n"); 

    size_t receiverSize = strlen(toName)+strlen(toEmail) + 30; 
    char *receiver = malloc(receiverSize); 
    snprintf(receiver, receiverSize, "%s%s (%s)%s", "To: ", toEmail, toName, "\r\n"); 

    size_t senderSize = strlen(fromEmail) + strlen(fromName) + 30; 
    char *sender = malloc(senderSize); 
    snprintf(sender, senderSize, "%s%s (%s)%s", "From: ", fromEmail, fromName, "\r\n"); 

    size_t timeSize = 40; 
    char* timeString = malloc(timeSize); 
    time_t rawtime = 0; 
    time(&rawtime); 
    struct tm *timeinfo = localtime(&rawtime); 
    strftime (timeString, timeSize, "Date: %a, %d %b %Y %T %z\r\n", timeinfo); 

    const char **payload = malloc(sizeof(char*) * 18); 
    const char* setup[] = 
    { 
     "MIME-Version: 1.0\r\n", 
     timeString, 
     receiver, 
     sender, 
     header, 
     // describe the data contained in the body 
     // https://tools.ietf.org/html/rfc2046#section-5.1.1 
     "Content-Type: multipart/alternative; boundary=border\r\n", 
     // empty line to divide headers from body, see RFC5322 
     "\r\n", 
     // all boundaries must start with two hyphens 
     "--border\r\n", 
     // let recipient interpret displaying text, send plain text & HTML 
     // specify the plain text encoding 
     "Content-Type: text/plain; charset=UTF-8\r\n", 
     "\r\n", 
     body, 
     "\r\n", 
     "--border\r\n", 
     // specify the HTML encoding 
     "Content-Type: text/html; charset=UTF-8\r\n", 
     "\r\n", 
     html, 
     "\r\n", 
     // final boundary ends with two hyphens as well 
     "--border--\r\n", 
     NULL 
    }; 

    int i; 
    for (i = 0; setup[i]; i++) { 
     *(payload + i) = setup[i]; 
    } 

    data->email = payload; 
    data->pos = 0; 
    return data; 
} 

size_t readCallback(char *ptr, size_t size, size_t nmemb, void *userp) 
{ 
    if((size == 0) || (nmemb == 0) || ((size * nmemb) < 1)) return 0; 

    EmailData *upload = (EmailData*) userp; 
    const char *email = upload->email[upload->pos]; 

    if(email) 
    { 
     size_t len = strlen(email); 
     if (len > size * nmemb) return CURL_READFUNC_ABORT; 
     memcpy(ptr, email, len); 
     upload->pos++; 
     return len; 
    } 
    return 0; 
} 


int sendMailUsingCurl(char* toEmail, char* toName,char* fromEmail, char* fromName, char* subject,char* body) { 


    CURLcode res = CURLE_OK; 
    struct curl_slist *recipients = NULL; 
    EmailData data = {0}; 
    initEmailData(&data,toEmail,toName,fromEmail,fromName,subject,body); 

    CURL *curl = curl_easy_init(); 

    if (curl) 
    { 
     // set username and password 
     curl_easy_setopt(curl, CURLOPT_USERNAME, "[email protected]"); 
     curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxxx"); 
     curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.x.com:25/"); 
     curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 
     curl_easy_setopt(curl, CURLOPT_MAIL_FROM, fromEmail); 

     recipients = curl_slist_append(recipients, toEmail); 
     curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); 

     curl_easy_setopt(curl, CURLOPT_READFUNCTION, readCallback); 
     curl_easy_setopt(curl, CURLOPT_READDATA, &data); 
     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); 
     // useful for debugging encryped traffic 
     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 

     // send the message 
     res = curl_easy_perform(curl); 
     if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); 
     curl_slist_free_all(recipients); 
     curl_easy_cleanup(curl); 
    } 

    return 1; 
} 

不幸的是,GDB没有返回任何东西,我不明白的代码错误,但仍然是没有发送任何。

每一条线索都会被认可。

回答

1

引用此行:354 End data with <CR><LF>.<CR><LF>

A "\r\n.\r\n"序列表示电子邮件数据的结束。所以,正确的

"--border--\r\n", 

之后添加

".\r\n", 

下一步,服务器则响应应该用250 OK。在250 OK之后,您应该回复QUIT。也许卷曲会正确照顾您的250 OK/QUIT互动。