Russian Qt Forum

Компиляторы и платформы => Linux => Тема начата: Авварон от Июль 14, 2009, 16:17



Название: mail
Отправлено: Авварон от Июль 14, 2009, 16:17
как посылать почту программно в линуксе? система - debian lenny, почтовый сервер exim4. гугл говорит открывать сокет и писать письмо руками, не кошерно. Есть ли нормальное апи для посылки почты?


Название: Re: mail
Отправлено: Rcus от Июль 14, 2009, 16:50
Гуглу надо правильно вопросы задавать, ключевое слово здесь "SMTP" (Simple Mail Transfer Protocol)
еще можно apt-cache search smtp library :)


Название: Re: mail
Отправлено: Авварон от Июль 14, 2009, 20:26
smtp юзать нежелательно. Потом по нему я тоже примеров кда не нашел, можно директлинк?
какие есть альтернативы смтп?


Название: Re: mail
Отправлено: Tonal от Июль 15, 2009, 08:31
SMTP (http://ru.wikipedia.org/wiki/SMTP) - это протокол отправки писем. Поэтому, если тебе нужно отправить письмо, то либо он, либо IMAP.


Название: Re: mail
Отправлено: Авварон от Июль 15, 2009, 10:01
а юзать его как? какая либа? да и сам хедер где взять?


Название: Re: mail
Отправлено: crackedmind от Июль 16, 2009, 02:37
Ну либу можно поискать на просторах инета.

Ну, и, если все таки программа делается на Qt, то в libqxt есть класс QxtSendMail.

p.s. Правда он использует программу sendmail. Которую можно и самому вызывать, и обойтись без Qxt


Название: Re: mail
Отправлено: Авварон от Июль 16, 2009, 08:06
к сожалению программа не на qt... нашел либу libesmtp в репах дебиана, похоже оно) правда апи как всегда через 1 место


Название: Re: mail
Отправлено: crackedmind от Июль 16, 2009, 08:28
Ну в любом случае, почему бы напрямую не вызывать sendmail?


Название: Re: mail
Отправлено: Авварон от Июль 16, 2009, 08:58
криво?:) вызовы system не тру:(


Название: Re: mail
Отправлено: BRE от Июль 16, 2009, 09:00
криво?:) вызовы system не тру:(
???
Посмотри на QProcess.


Название: Re: mail
Отправлено: BRE от Июль 16, 2009, 09:10
Кстати в Qt3 был пример отправки сообщения используя SMTP на несколько сотен строк. Протокол то простой.  ;)


Название: Re: mail
Отправлено: spirit от Июль 16, 2009, 09:17
вот есть класс (http://doc.libqxt.org/latest/classQxtSendmail.html), вот только не уверен, что он бесплатный.
ссылку обновил.


Название: Re: mail
Отправлено: Авварон от Июль 16, 2009, 09:23
spirit
дома гляну реализацию, спасибо

BRE да, я видел) в 1м посте я в том числе его и упоминал) мб и заюзаю...


Название: Re: mail
Отправлено: Rcus от Июль 16, 2009, 09:33
Кстати в Qt3 был пример отправки сообщения используя SMTP на несколько сотен строк. Протокол то простой.  ;)
Тоньше надо :) SMTP простой пока используется ASCII без аттачей, а дальше на каждое расширение протокола по RFC :)


Название: Re: mail
Отправлено: Alex Custov от Июль 16, 2009, 16:29
Как раз этим занимаюсь. Использовать надо любого клиента к MTA. Например, попроще - jwsmtp. Код такой:

Код
C++ (Qt)
   jwsmtp::mailer m("tome@gmail.com",
                       "fromme@gmail.com",
                       "bugreport",
                       "Hello",
                       "localhost",
                       jwsmtp::mailer::SMTP_PORT,
                       false);
 
   // аттач
   m.attach("/tmp/report.txt");
 
   // отправка
   m.send();
 
   QString response = m.response().c_str();
 
   if(response.startsWith("250"))
       qDebug("Success");
   else
       qDebug("Failed");
 

Посложнее и покруче - libesmtp (есть в Debian). Документация тут (http://www.stafford.uklinux.net/libesmtp/api.html).

Проблемы: нет гарантии доставки письма. Если письмо корректно сформировано (с точки зрения синтаксиса), то exim сразу ответит "250 OK", и ты будешь думать, что письмо ушло. Но если exim по какой-то причине не сможет доставить это письмо (несуществующий обратный адрес, др.), то письмо не уйдёт и узнать об этом можно будет из лога /var/log/exim4/mainlog. Возможно, в отслеживании статуса письмо поможет libesmtp с ETRN, но я это ещё не щупал.


Название: Re: mail
Отправлено: Авварон от Июль 16, 2009, 16:43
сслыку на esmtp тоже видел:) беглым взглядом не увидел сильных отличий от мана, хотя в общем на сайте инфы больше... спасибо, буду разбираться:)
а jwsmtp отдельно качать\собирать из сорцов надо? бегло в репах не нашел


Название: Re: mail
Отправлено: Alex Custov от Июль 16, 2009, 16:49
сслыку на esmtp тоже видел:) беглым взглядом не увидел сильных отличий от мана, хотя в общем на сайте инфы больше... спасибо, буду разбираться:)
а jwsmtp отдельно качать\собирать из сорцов надо? бегло в репах не нашел

в репах нет, надо качать и собирать deb пакет. Если не компилится в Lenny, надо наложить патч.

Код
Diff
diff -ruN jwsmtp-1.32.13.orig/jwsmtp/demo2.cpp jwsmtp-1.32.13/jwsmtp/demo2.cpp
--- jwsmtp-1.32.13.orig/jwsmtp/demo2.cpp 2006-01-27 03:17:08.000000000 +0200
+++ jwsmtp-1.32.13/jwsmtp/demo2.cpp 2009-07-03 15:02:54.000000000 +0300
@@ -21,6 +21,7 @@
//#include <boost\thread\thread.hpp>
 
#include <iostream>
+#include <cstring>
#include "jwsmtp/jwsmtp.h"
 
using std::cout;
diff -ruN jwsmtp-1.32.13.orig/jwsmtp/jwsmtp/mailer.cpp jwsmtp-1.32.13/jwsmtp/jwsmtp/mailer.cpp
--- jwsmtp-1.32.13.orig/jwsmtp/jwsmtp/mailer.cpp 2006-07-04 19:51:32.000000000 +0300
+++ jwsmtp-1.32.13/jwsmtp/jwsmtp/mailer.cpp 2009-07-03 15:02:43.000000000 +0300
@@ -28,6 +28,8 @@
#include <sstream>   // ostrstream
#include <ctime>     // for localtime
#include <cassert>
+#include <cstring>
+#include <cstdlib>
#include "mailer.h"
#include "base64.h"
 

P.S. Почему стало нельзя делать аттачи?


Название: Re: mail
Отправлено: Авварон от Июль 17, 2009, 10:22
вот нашел пример юзания libesmtp. Код взят с китайского  сайта-_-, работоспособность не проверял...
Код:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <stdarg.h>

#include <libesmtp.h>

int main() {
    smtp_session_t session;
    smtp_message_t message;
    struct sigaction sa;
    const smtp_status_t *status;
    char buf[128];
    FILE *fp;
    /* This program sends only one message at a time.  Create an SMTP
       session and add a message to it. */
    if( (session = smtp_create_session ())  == NULL){
        fprintf (stderr, "smtp_create_session problem %s\n",
                smtp_strerror (smtp_errno (), buf, sizeof buf));
        return 1;
    }
    if((message = smtp_add_message (session)) == NULL){
        fprintf (stderr, "smtp_add_message problem %s\n",
                smtp_strerror (smtp_errno (), buf, sizeof buf));
        return 1;
    }
    /* NB.  libESMTP sets timeouts as it progresses through the protocol.
       In addition the remote server might close its socket on a timeout.
       Consequently libESMTP may sometimes try to write to a socket with
       no reader.  Ignore SIGPIPE, then the program doesn't get killed
       if/when this happens. */
    sa.sa_handler = SIG_IGN;
    sigemptyset (&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction (SIGPIPE, &sa, NULL); 
    /* Set the host running the SMTP server.  LibESMTP has a default port
       number of 587, however this is not widely deployed so the port
       is specified as 25 along with the default MTA host. */
    smtp_set_server (session, "127.0.0.1:25");
    /* Set the reverse path for the mail envelope.  (NULL is ok)
     */
    smtp_set_reverse_path (message, "test@test.com");
    /* RFC 2822 doesn't require recipient headers but a To: header would
     *      be nice to have if not present. */
    smtp_set_header (message, "To", NULL, NULL);
    smtp_set_header (message, "Subject", " test mail");
    smtp_set_header_option (message, "Subject", Hdr_OVERRIDE, 1);
    fprintf(stderr,"%s\n","smtp_set_server.");
    if ((fp = fopen ("test-mail.eml", "r")) == NULL) {
        fprintf (stderr, "can't open mail file: %s\n", strerror (errno));
        return (1);
    }
    smtp_set_message_fp (message, fp);
    smtp_add_recipient (message,"test@localhost");
    /* Initiate a connection to the SMTP server and transfer the
       message. */
    if (!smtp_start_session (session)){
        fprintf (stderr, "SMTP server problem %s\n",
                smtp_strerror (smtp_errno (), buf, sizeof buf));
    }
    else{
        /* Report on the success or otherwise of the mail transfer.
        */
        status = smtp_message_transfer_status (message);
        printf ("%d %s", status->code,
                (status->text != NULL) ? status->text : "\n");
    }
    /* Free resources consumed by the program.
    */
    smtp_destroy_session (session);
    if(fp != NULL){
        fclose(fp);
    }

    return 0;
}


Название: Re: mail
Отправлено: Авварон от Июль 20, 2009, 10:59
по поводу libesmtp - ни фига не работает:( Приходит пустое сообщение, хотя все теги заголовка прописываются правильно - нет только тела... причем странно нет - энтеры есть) возможно это косяк аутлука или exchange'а...
jwsmtp вроде работает:)