Dm3Ch
Dm3Ch

Reputation: 761

C/C++ program not correctly works on Raspberry Pi


I have written program, that sends 5 emails through my gmail adress, with 1 minute pause between. This program works on my laptop, but not works on Raspberry Pi. On Raspberry Pi it sends only 1 email.

main.cpp:

#include <string>
#include <thread>
#include <chrono>

#include "email.c"

void threadFunction()
{
    for (int i = 0; i < 5; i++)
    {
        std::string message = /*"Hello my name is Dmitry\r\nTest1\r\nTest2\r\n" + */std::to_string(i) + "\r\n";
        int status = sent_email("*********", "*********", "Test message", message.c_str(), "smtps://smtp.gmail.com", "*********", "*********");
        std::this_thread::sleep_for(std::chrono::minutes(1));
        status++;
    }
}

int main()
{
     /*std::thread thr(threadFunction);
     thr.join();*/
     threadFunction();
     return 0;
}

email.c:

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

struct upload_information {
    const char *data;
    size_t data_length;
    size_t sent;
};

size_t read_callback(char *buffer, size_t size, size_t nitems, void *instream);

int sent_email(const char *FROM, const char *TO, const char *SUBJECT, const char *message, const char *server, const char *login, const char *password)
{
    CURL *curl;
    CURLcode res = CURLE_OK;
    struct curl_slist *recipients = NULL;

    size_t length = strlen(message) + strlen(FROM) + strlen(TO) + strlen(SUBJECT) + 32; //32 is FROM: <>/n/r, TO: <>/n/r length and SUBJECT + new line(after header - SMTP standart) + /0

    char *data;
    data = (char*)malloc(sizeof(char) * length);

    strcat(data, "FROM: <");
    strcat(data, FROM);
    strcat(data, ">\r\n");
    strcat(data, "TO: <");
    strcat(data, TO);
    strcat(data, ">\r\n");
    strcat(data, "SUBJECT: ");
    strcat(data, SUBJECT);
    strcat(data, "\r\n\r\n");
    strcat(data, message);

    struct upload_information upload_info;
    upload_info.data = data;
    upload_info.data_length = length;
    upload_info.sent = 0;

    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_USERNAME, login);
        curl_easy_setopt(curl, CURLOPT_PASSWORD, password);

        curl_easy_setopt(curl, CURLOPT_URL, server);

        curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
        recipients = curl_slist_append(recipients, TO);
        //recipients = curl_slist_append(recipients, CC);
        curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
        curl_easy_setopt(curl, CURLOPT_READDATA, &upload_info);
        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        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);
    }

    free(data);
    return (int)res;
}

size_t read_callback(char *buffer, size_t size, size_t nitems, void *instream)
{
    struct upload_information *upload_info = (struct upload_information *)instream;

    if ((size == 0) || (nitems == 0) || (size * nitems < 1))
        return 0;

    if (upload_info->sent < upload_info->data_length)
    {
        size_t length = size * nitems;

        if (length > upload_info->data_length - upload_info->sent)
            length = upload_info->data_length - upload_info->sent;

        memcpy(buffer, upload_info->data + upload_info->sent, length);

        upload_info->sent += length;

        return length;
    }

    return 0;
}

Error message on Raspberry Pi:
*** glibc detected *** ./Mailer: double free or corruption (!prev): 0x01d0da38 ***

P.S. Program on raspberry pi send 1 correct message and part of second message.
P.S.S Post was updated

Upvotes: 1

Views: 841

Answers (2)

Dm3Ch
Dm3Ch

Reputation: 761

I have solved my problem. Problem was because of when i freeв memory i am not reset memory.

I add *data = '\0'; befor strcat.

Upvotes: 0

Ross Ridge
Ross Ridge

Reputation: 39631

The buffer you're allocating for the message is 1 byte to short. The total length of all the constant strings you're adding is 29, but you also need to add one more byte for the '\0' character that strcat will terminate the string with.

If you run the following code it shows you that concatenated length of all the string literals is 30:

#include <stdio.h>

int
main() {
    printf("%d\n", (int) sizeof("FROM: <" ">\r\n"
                                "TO: <" ">\r\n"
                                "SUBJECT: " "\r\n"));
}

There are two other problem with the message. One is that you're not putting a blank line between the headers and the message as required. The other is that you're not terminating the final line of the message with \r\n. This might confuse the curl library as it will need to add the end of line terminator itself. If it doesn't the message won't be sent through SMTP correctly.

Upvotes: 4

Related Questions