Newsgroup: it.comp.programmare.win32
Titolo: codice per invio email

scusate se posto l'intero prg (non e' molto lungo) .
Cosa gli manca secondo Voi perche mi dice che la mail e' stata inviata
correttamente pero non arriva niente.
#include <stdio.h>
#include <io.h>
#include <stdio.h>
//#define LINUX /* define this if you are on linux   */
//#define WIN32 /* define this if you are on windows */
#ifdef WIN32
#       include "io.h"
#       include "winsock2.h"      /* WSAGetLastError, WSAStartUp  */
#       define snprintf _snprintf
#endif
#ifdef LINUX
#       include <netdb.h>         /* gethostbyname  */
#       include <netinet/in.h>    /* htons          */
#       include <sys/socket.h>
#endif
static void sendmail_write(
                const int  sock,
                const char *str,
                const char *arg
            ) {
    char buf[4096];
    if (arg != NULL)
        snprintf(buf, sizeof(buf), str, arg);        
    else
        snprintf(buf, sizeof(buf), str);
 
    send(sock, buf, strlen(buf), 0);    
}
static int sendmail(
                const char *from,
                const char *to,
                const char *subject,
                const char *body,
                const char *hostname,
                const int   port
            ) {
    struct hostent *host;   
    struct sockaddr_in saddr_in;
    int sock = 0;
#ifdef WIN32
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		return -1;
	}
#endif
    sock = socket(AF_INET, SOCK_STREAM, 0);
	host = gethostbyname(hostname);
 
	saddr_in.sin_family      = AF_INET;
	saddr_in.sin_port        = htons((u_short)port);
	saddr_in.sin_addr.s_addr = 0;
	memcpy((char*)&(saddr_in.sin_addr), host->h_addr,
host->h_length);
	if (connect(sock, (struct sockaddr*)&saddr_in,
sizeof(saddr_in)) == -1) {
		return -2;
	}
 
    sendmail_write(sock, "HELO %s\n",       from);    // greeting
    sendmail_write(sock, "MAIL FROM: %s\n", from);    // from
    sendmail_write(sock, "RCPT TO: %s\n",   to);      // to
    sendmail_write(sock, "DATA\n",          NULL);    // begin data
    // next comes mail headers
    sendmail_write(sock, "From: %s\n",      from);
    sendmail_write(sock, "To: %s\n",        to);
    sendmail_write(sock, "Subject: %s\n",   subject);
    sendmail_write(sock, "\n",              NULL);
    sendmail_write(sock, "%s\n",            body);    // data
    sendmail_write(sock, ".\n",             NULL);    // end data
    sendmail_write(sock, "QUIT\n",          NULL);    // terminate
    close(sock);
    return 0;
}
int main(int argc, char *argv[]) {
 
    int ret = sendmail(
        "
fr...@from-host.org
",   /* from     */
        "
t...@to-host.org
",       /* to       */
        "Subject",              /* subject  */
        "body",                 /* body     */
        "hostname",             /* hostname */
        25                      /* port     */
    );
    if (ret != 0)
        fprintf(stderr, "Failed to send mail (code: %i).\n", ret);
    else
        fprintf(stdout, "Mail successfully sent.\n");
    return ret;
}

 wrote:
[cut]
Non ho esaminato a fondo il tuo codice perché sbagli un concetto di
fondo, banale ma essenziale: la comunicazione tra il tuo client e il
server deve essere asincrona, non puoi spedire tutti i comandi di
colpo.
Esempio: 
usi una variabile di stato che incrementi ad ogni passo, inizi con
stato=0 la comunicazione con il server mandando il comando HELO e
aspetti una risposta. 
Se la risposta è ok (vedi le varie rfc) allora stato++ e poi passi al
comando MAIL FROM, se la risposta è ok allora stato++ e vai avanti.
In questo modo sei sicuro che eventuali ritardi di propagazione dei
tuoi comandi (causa traffico internet, provider che fa le bizze,
lentezza del mail server,  etc) non arrivino prima che il server abbia
"digerito" i comandi precedenti.
So che in questo modo funziona avendo scritto una dll in C (usabile
anche in VB) che implementa quanto stai scrivendo tu :-)
Ciao
Stefano "HappyMan" (Lago Maggiore - NO)
--
Personal Web 
http://www.sgr.info
Email happyman69 (at) 
libero.it

 comando MAIL FROM, se la risposta è ok allora stato++ e vai avanti.
Interessa anche a me... ed essendo un niubbo praticamente totale ti chiedo
dove posso trovare maggiori info sui comandi di risposta dati dal server.
Grazie!
-- 
Andrea
I plagiari sospettano sempre che qualcuno li derubi del loro pensiero.
(Samuel Taylor Coleridge)

 dove posso trovare maggiori info sui comandi di risposta dati dal server.
quoto perchè interessa anche me..
è posibile avere il codice se l'hai corretto?
grazie

"FRaNCeSCo" <?@?.?> ha scritto nel messaggio
news:X558b.48463$hE5.1...@news1.tin.it...

Qualcosa di più concreto.
Basta scaricare le varie RFC che sono gratuite per tutti, ad esempio:
http://www.faqs.org/rfcs/
nello specifico guardate quanto riportato nella RFC821
(SIMPLE MAIL TRANSFER PROTOCOL)
praticamente tutte le applicazioni, ad esempio in VB, che implementano la
trasmissione di e-mail utilizzano una connessione
Telnet alla porta 25 ed in seguito inviano i comandi previsti dalla RFC821
attendendo le risposte dal server, ovviamente
il tempo di attesa viene limitato ad esempio a 6 s per evitare di rimenere
in attesa all'infinito qualora la connessione
dovesse interrompersi per qualsiasi motivo.
Di seguito riporto un esempio di codice molto semplice e da rifinire che
faci tempo fa.
Si può modificare per consentire la trasmissione di allegati utilizzando il
protocollo MIME codificando i dati
in base 64. Il concetto comunque ti serve per capire dove devi attendere le
risposte dal server prima di
procedere con l'invio di altri comandi /dati.
L'applicazione è costituita solo da un form con alcune caselle di testo e
label ed un controllo di tipo Winsock (usato
per stabilire la connessione con il protocollo TCP/IP verso la porta 25 del
server della posta).
Eventualmente usate telnet scrivendo:
telnet 
mail.libero.it
 25 (invio)
ed iniziate a sperimentare "a mano" il protocollo e le risposte dal server.
L'elenco dei comandi supportati dal server lo ottenete digitando:
help (invio)
Digitando quanto sopra riportato si dovrebbe ottenere qcsa del genere:
220 
smtp0.libero.it
 ESMTP Service (7.0.020-DD01) ready
help
214-Valid SMTP commands:
214-  HELO, EHLO, NOOP, RSET, QUIT, STARTTLS
214-  MAIL, RCPT, DATA, VRFY, EXPN, HELP, ETRN
214-For more info, use HELP <valid SMTP command>
214 end of help
****************************************************************************
****
INIZIO CODICE
****************************************************************************
****
' ----------------------------------------------------
' Applicazione  : WinsockMail
' Scopo         : invio e-mail secondo standard RFC822
' Autore        : Powermos
' Data creazione: 05/11/2002
' Revisione     : 0 - Prima emissione
' ----------------------------------------------------
Public strIncoming As String
Private Sub DelayTime(Time As Integer)
S = Timer
Do While Timer < (S + Time)
 DoEvents
Loop
End Sub
Private Sub Delay()
Do While (strIncoming = "")
DoEvents
Loop
strIncoming = ""
lblStatusConnection = "Message from Mail server received ..."
End Sub
Private Sub BtnOpenConnection_Click()
If (txtAddress.Text = "") Then
 Temp = MsgBox("Inserire un nome di server valido", vbOKOnly Or
vbExclamation, "User Information")
 txtAddress.Text = "mail nomeserver.xx oppure nn.nn.nn.nn"
 Exit Sub
End If
' Verifica se la connessione al server della posta è già stata attivata
If ((Winsock1.RemotePort = 25) And (Winsock1.State = sckConnected)) Then
 Temp = MsgBox("Mail server già connesso", vbOKOnly Or vbExclamation, "User
Information")
 Exit Sub
End If
' Attivo la connessione con il server
Winsock1.Close                          ' Chiude eventuali connessioni
precedenti
Winsock1.Protocol = sckTCPProtocol      ' Imposta protocollo TCP/IP
Winsock1.RemoteHost = txtAddress.Text   ' Imposta indirizzo server della
posta
Winsock1.RemotePort = 25                ' Imposta la porta in ingresso al
server della posta
Winsock1.Connect                        ' Stabilisce una connessione
Delay
lblStatusConnection = "Connecting server on port: " +
Format(Winsock1.RemotePort)
' Invia comandi di inizializzazione
Winsock1.SendData "RSET" + Chr(13) + Chr(10)
Delay
Winsock1.SendData "HELO 
ciao.it
" + Chr(13) + Chr(10)
Delay
'Abilita pulsante per invio e-mail
BtnSndMail.Enabled = True
End Sub
Private Sub BtnSndMail_Click()
If (FromTo.Text = "") Then
Temp = MsgBox("Inserire FROM TO: valido", vbOKOnly Or vbExclamation, "User
Information")
 Exit Sub
End If
If (RcptTo.Text = "") Then
Temp = MsgBox("Inserire RCPT TO: valido", vbOKOnly Or vbExclamation, "User
Information")
 Exit Sub
End If
' Tutti i campi sono corretti, invia il testo della mail
' Winsock1.SendData "MAIL FROM:" + "<" + FromTo.Text + ">" + Chr(13) +
Chr(10)
Winsock1.SendData "MAIL FROM:" + FromTo.Text + Chr(13) + Chr(10)
Delay
' Winsock1.SendData "RCPT TO:" + "<" + RcptTo.Text + ">" + Chr(13) + Chr(10)
Winsock1.SendData "RCPT TO:" + RcptTo.Text + Chr(13) + Chr(10)
Delay
Winsock1.SendData "DATA" + Chr(13) + Chr(10)
Delay
Winsock1.SendData txtMailMessage.Text + Chr(13) + Chr(10)
lblStatusConnection = "Sending mail in progress ..."
DelayTime (6)
Winsock1.SendData Chr(13) + Chr(10)
DelayTime (6)
Winsock1.SendData "." + Chr(13) + Chr(10)
DelayTime (6)
Winsock1.SendData Chr(13) + Chr(10)
Delay
Winsock1.Close
lblStatusConnection = "Sending mail done"
DelayTime (2)
' Inizializza sistema per prossima e-mail
Form_Load
End Sub
Private Sub Form_Load()
' Disabilito il pulsante per l'invio delle e-mail
BtnSndMail.Enabled = False
' Visualizzo lo stato corrente della connessione
lblStatusConnection = "No connection is present ..."
' Inizializza buffer messaggi in ingresso dal server della posta
strIncoming = ""
' Imposta campo Server Mail name
txtAddress = "mail servername.xx oppure nn.nn.nn.nn"
End Sub
Private Sub Form_Unload(Cancel As Integer)
' Chiudo la connessione con il server della posta
Winsock1.Close
End Sub
Private Sub Winsock1_Close()
' Il server della posta ha chiuso la connessione
lblStatusConnection = "Mail server is go off-line ..."
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
' Visualizza i dati in arrivo dal server della posta
Winsock1.GetData strIncoming
txtIncomingMessage.Text = strIncoming
lblStatusConnection = "Message from server received ..."
End Sub
****************************************************************************
****
FINE CODICE
****************************************************************************
****
Ciao
Pow
--
----------------------------------------------------
Ama il tuo mestiere con passione
E' il significato della tua vita
Auguste Rodin (1840-1917)
 "Not everything that  counts can be
 counted, and not everything that can
be counted counts".
Albert Einstein
"Hunt for the Engineer and the Engineer will hunt you."
Hellraiser5 Pinhead