Entra

View Full Version : Inviare mail con C++


leon84
01-06-2004, 14:36
Da un'applicazione consolle com'è possibile inviare una mail ?

ariagiovannifanboy
03-06-2004, 01:59
Ci sono un po' di modi:

- Usare la MAPI, richiede pero' che hai installato Outlook (di Office, non l'express).

- Gestirti il protocollo SMTP usando i socket

- Trovare una libreria terze parti che gestisce l'SMTP da sola

LukeHack
03-06-2004, 03:40
Originariamente inviato da leon84
Da un'applicazione consolle com'è possibile inviare una mail ? :sofico: ti devi creare tre file mailer.ini sender.ini rcpt.ini con i rispettivi valori
#include <winsock.h>
#include <ostream.h>
#include <stdio.h>
#include <string>
using namespace std;

SOCKET to_server_socket = 0;
//char server_name[] = "smtp.fastwebnet.it"; // Changer SERVEUR par le nom du serveur
int port = 25;
char sender[100],server_name[100],rcpt[100];
FILE* fp;


void bcopy( void * source, void * destination, int size )
{
char * src = ( char * ) source;
char * dst = ( char * ) destination;

for( int i=0; i<size; i++ )
dst[i] = src[i];
}



void bzero( void * destination, int size )
{
char * dst = ( char * ) destination;

for( int i=0; i<size; i++ )
dst[i] = 0x00;
}



void Process( char * buffer )
{
Sleep( 1000 );
cerr << "Envoye < " << buffer << endl;
int size = strlen( buffer );
int retVal = send( to_server_socket, buffer, size, 0 );

char buf[ 1024 ];
buf[0] = 0x00;
while( !buf[0] )
int yeah = recv( to_server_socket, buf, 1024, 0 );
cerr << "Recu > " << buf << endl << endl;
}



int main( int argc, char *argv[] )
{
int not = 0;
unsigned long ioctl_blocking = 1;

fp = fopen("mailer.ini","r");
fscanf(fp,"%s",server_name);
fclose(fp);

fp = fopen("sender.ini","r");
fscanf(fp,"%s",sender);
fclose(fp);

fp = fopen("rcpt.ini","r");
fscanf(fp,"%s",rcpt);
fclose(fp);



WSADATA wsaData;
if( int err = WSAStartup( 0x0101, &wsaData ) )
{
cerr << "WSAStartup failed... Error: " << err << endl;
exit( -1 );
}


struct sockaddr_in serverSockAddr; // addresse de la socket
struct hostent * serverHostEnt; // description du host serveur
long hostAddr; // addr du serveur

bzero( &serverSockAddr, sizeof( serverSockAddr ) );
// initialise a zero serverSockAddr
hostAddr = inet_addr( server_name );
// converti l'adresse ip 9.100.1.1 en entier long

// if( ( long ) hostAddr != ( long ) -1 )
// bcopy( &hostAddr, &serverSockAddr.sin_addr, sizeof( hostAddr ) );
//else // si on a donne un nom
//{


serverHostEnt=NULL;
while(!serverHostEnt)
{
serverHostEnt = gethostbyname( server_name );
if ( serverHostEnt == NULL )
{
cerr << "ca chie gethost" << endl;
//exit( 0 );
}
else cout<<"CONNESSO!";
//Sleep(10000);

}
bcopy( serverHostEnt->h_addr, &serverSockAddr.sin_addr, serverHostEnt->h_length );
//}

serverSockAddr.sin_port = htons( port ); // host to network port
serverSockAddr.sin_family = AF_INET; // AF_*** : INET=internet
// creation de la socket
while (true)
{
to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );
if ( to_server_socket < 0)
{
cerr << "ca chie creation socket client" << endl;
exit( 0 );
}

setsockopt(to_server_socket, SOL_SOCKET, SO_DONTLINGER, (char *) &not, sizeof(not));


// requete de connexion
if( connect( to_server_socket, (
struct sockaddr * ) &serverSockAddr, sizeof( serverSockAddr ) ) < 0 )
{
cerr << "ca chie demande de connection" << endl;
exit( 0 );
}

ioctlsocket ( to_server_socket, FIONBIO, &ioctl_blocking );

char buf[ 1024 ];
buf[0] = 0x00;
while( !buf[0] )
int yeah = recv( to_server_socket, buf, 1024, 0 );
cerr << "Receive > " << buf << endl << endl;

Process( "HELO helio_denis\r\n" );
string a1="MAIL From: <";
a1 += sender;
a1 += ">\r\n";
char * aux1=new char[a1.length()];
for (int h=0;h<a1.length();h++)
aux1[h]=a1[h];
aux1[h]='\0';
Process( aux1); // Changer ADD FROM par le mail de l'expediteur
//delete aux1;

a1="RCPT To: <";
a1 += rcpt;
a1 += ">\r\n";
aux1=new char[a1.length()];
for (h=0;h<a1.length();h++)
aux1[h]=a1[h];
aux1[h]='\0';
Process( aux1); // Changer ADD FROM par le mail de l'expediteur
//delete aux1;

Process( "DATA\r\n" );

a1="From: ";
a1+=sender;
a1+="\r\nTo: ";
a1+=rcpt;
a1+="\r\nSubject: IP di ";
a1+=sender;
a1+="\r\n\r\n";
a1+="\r\n.\r\n";
aux1=new char[a1.length()];
for (h=0;h<a1.length();h++)
aux1[h]=a1[h];
aux1[h]='\0';
Process( aux1);


Process( "QUIT\r\n" );
//shutdown( to_server_socket, 2 );
closesocket( to_server_socket );
}

return( closesocket( to_server_socket ) );
}

leon84
03-06-2004, 19:02
Scusa ma nei tre file cosa ci devo mettere ?

NA01
03-06-2004, 20:24
non mi sembra che il codice postato regga l'autenticazione (magari mi sbaglio, ho solo dato una veloce occhiata).
in tal caso devi essere sicuro che il tuo server smtp non la voglia (e ormai sono pochi :cry: , il mio vecchio programma è andato a catafascio per questo, non sono mai riuscito a capire cosa diavolo deve fare per autenticarsi :D ).

leon84
03-06-2004, 21:11
Scusa che significa ?

leon84
03-06-2004, 23:06
Ragazzi ho risolto col seguente modo : Siccome col comando system("comando dos") posso inviare qualsiasi comando al prompt, mi apro una sessione telnet sulla porta 25 e invio la mail .... secondo voi è carica come cosa ???? Almeno mi risparmio molto codice....

LukeHack
03-06-2004, 23:28
Originariamente inviato da leon84
Ragazzi ho risolto col seguente modo : Siccome col comando system("comando dos") posso inviare qualsiasi comando al prompt, mi apro una sessione telnet sulla porta 25 e invio la mail .... secondo voi è carica come cosa ???? Almeno mi risparmio molto codice....
uno schifo totale:D dammi retta,studiati il codice postato che si basa sui SOCKET concetto importantissimo nella programmazione su rete

LukeHack
03-06-2004, 23:34
Originariamente inviato da NA01
non mi sembra che il codice postato regga l'autenticazione (magari mi sbaglio, ho solo dato una veloce occhiata).
in tal caso devi essere sicuro che il tuo server smtp non la voglia (e ormai sono pochi :cry: , il mio vecchio programma è andato a catafascio per questo, non sono mai riuscito a capire cosa diavolo deve fare per autenticarsi :D ).
beh con il protocollo classico riesco a mandare il 100% delle email,fai un pò tu:D
infatti l'smtp server si frega facilmente:D
infatti supponiamo che tu debba mandare una email a tizio@tin.it
e il tuo provider è tiscali... ora, se tu mandi una mail da un altro account (per es libero) è sufficiente che metti come smtp smtp.tiscali.it... infatti esso vede che dall'ip sei su tiscali e accetta di tutto...questo al 90% dei casi funge (Almeno per mia esperienza); altrimenti,altro trucchetto è il comando nslookup -q=mx <provider di arrivo> (x ipotesi tin.it)...
lui ti fornirà il server MX ossia l'exchange smtp,vale a dire l'ultimo nodo che smista le email ai pop... bene,questi accettano di tutto, PURCHE' il destinatario (rcpt) ESISTA (Esso infatti provvede alla verifica dell'esistenza di tizio@tin.it)

quindi mandare email,anche anonime è molto semplice,infatti i controlli a colabrodo e le autenticazioni si fregano almeno con questi due metodi:D

LukeHack
03-06-2004, 23:35
Originariamente inviato da leon84
Scusa ma nei tre file cosa ci devo mettere ?
indovina un pò?
l'smtp, il mittente (te) e il destinatario

NA01
04-06-2004, 06:33
a me da
550 relay not allowed
uso solo katamail, email e fw.
devo impostare la password in uscita, ma non capisco come si mandi (non è un'autenticazione in chiaro da quanto ho capito)

ciao

leon84
04-06-2004, 06:46
Originariamente inviato da LukeHack
indovina un pò?
l'smtp, il mittente (te) e il destinatario


posso mettere anche più di un destinatario ?

LukeHack
04-06-2004, 13:04
Originariamente inviato da NA01
a me da
550 relay not allowed
uso solo katamail, email e fw.
devo impostare la password in uscita, ma non capisco come si mandi (non è un'autenticazione in chiaro da quanto ho capito)

ciao
il motivo è proprio quello scritto prima,ossia tu non appartieni a kataweb IN QUANTO AD IP e quindi non PUOI fare relaying...
ma ti basta usare come smtp quello del tuo PROVIDER, che sta barriera dovresti superarla,sennò c'è il secondo ttrucchetto e quello è un pò come la chiave universale di Diabolik ;)
fammi sapere ciao :)

LukeHack
04-06-2004, 13:06
Originariamente inviato da leon84
posso mettere anche più di un destinatario ?
non ci ho mai provato,prova a mettercene 2 o 3 separati da ;
vediamo he succede:)

cionci
04-06-2004, 13:08
Per l'auteticazione è facile....
http://www.technoids.org/saslmech.html#appB (AUTH LOGIN)

Ovviamente bisogna fare una codifica base64 di username e password... Se volte gli algoritmi di codifica e decodifica ce li ho, fatti in C...

LukeHack
04-06-2004, 13:14
Originariamente inviato da cionci
Per l'auteticazione è facile....
http://www.technoids.org/saslmech.html#appB (AUTH LOGIN)

Ovviamente bisogna fare una codifica base64 di username e password... Se volte gli algoritmi di codifica e decodifica ce li ho, fatti in C...
postali che non fa mai male ;)
anche se non ho mai avuto problemi senza autenticazione, può sempre tornare utile :D

NA01
04-06-2004, 13:15
me li fai vedere?
così aggiorno il programmino :D (totalmente inutile dato che uso sylpheed claws, ma è il mio primo programma :cry: )
credevo servisse una cosa tipo cifratura in md5 :eek:

meglio così!

grazie,
ciao

leon84
04-06-2004, 13:23
già che ci siamo posto un'altra domandina ....

ho già una connessione remota configurata ..... voglio poterla connettere e poi disconnettere quando voglio sempre dal programma in C++ .... è difficile ?

NA01
04-06-2004, 13:30
Originariamente inviato da LukeHack
il motivo è proprio quello scritto prima,ossia tu non appartieni a kataweb IN QUANTO AD IP e quindi non PUOI fare relaying...
ma ti basta usare come smtp quello del tuo PROVIDER, che sta barriera dovresti superarla,sennò c'è il secondo ttrucchetto e quello è un pò come la chiave universale di Diabolik ;)
fammi sapere ciao :)
email.it consente solo la connessione alla casella di posta, no ha connessioni proprie

ciao

cionci
04-06-2004, 13:34
Ecco qua:#include <iostream>
#include <string>

using namespace std;

string Base64Encode(const string &data)
{
const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int dataLen = data.length();
string res;

for(int i=0; i<dataLen; i+=3)
{
unsigned int triplet;
char tmp[5];

triplet = (data[i] << 16)
+ (((dataLen > (i+1))?data[i+1]:0) << 8)
+ ((dataLen > (i+2))?data[i+2]:0);

tmp[3] = base64[triplet & 0x3F];
tmp[2] = base64[(triplet >> 6) & 0x3F];
tmp[1] = base64[(triplet >> 12) & 0x3F];
tmp[0] = base64[(triplet >> 18) & 0x3F];
tmp[4] = '\0';

res.append(tmp);
}
switch(dataLen % 3)
{
case 1:
res[res.length()-2] = '=';
case 2:
res[res.length()-1] = '=';
}
return res;
}

inline int getBase64Pos(const char c)
{
switch(c)
{
case '+':
return 62;
case '/':
return 63;
default:
if(c >= 'A' && c <= 'Z')
return c - 'A';
else if(c >= 'a' && c <= 'z')
return 26 + c - 'a';
else if(c >= '0' && c <= '9')
return 52 + c - '0';
else
return 0;
}
return -1;
}


string Base64Decode(const string &data)
{
unsigned int dataLen = data.length();
string res("");

if(res[dataLen-1] == '=')
--dataLen;
if(res[dataLen-1] == '=')
--dataLen;

unsigned int buf;
char tmp[4];

for(int i=0; i<dataLen; i+=4)
{
int t1 = 0, t2 = 0, t3 = 0, t4 = 0;

buf = 0;
t1 = getBase64Pos(data[i]);
t2 = getBase64Pos((dataLen > (i+1)) ? data[i+1]:'A');
t3 = getBase64Pos((dataLen > (i+2)) ? data[i+2]:'A');
t4 = getBase64Pos((dataLen > (i+3)) ? data[i+3]:'A');

if(t1 < 0 || t2 < 0 || t3 < 0 || t4 < 0)
return res;

tmp[0] = (t1 << 2) + (t2 >> 4);
tmp[1] = (t2 << 4) + (t3 >> 2);
tmp[2] = (t3 << 6) + t4;
tmp[3] = '\0';

res.append(tmp);
}

return res;
}

leon84
04-06-2004, 14:09
Anzi semplifichiamo la cosa :

mettiamo che con le operazioni pianificate di windows voglio connettermi ad una certa ora e sconnettermi ad un'altra ora .... come si può fare ?

LukeHack
04-06-2004, 14:33
Originariamente inviato da NA01
email.it consente solo la connessione alla casella di posta, no ha connessioni proprie

ciao
si ma qual'è il tuo provider? fastweb? se cosi usa smtp.fastwebnet.it
e stai aposto! (per mandare email)

LukeHack
04-06-2004, 14:34
Originariamente inviato da leon84
Anzi semplifichiamo la cosa :

mettiamo che con le operazioni pianificate di windows voglio connettermi ad una certa ora e sconnettermi ad un'altra ora .... come si può fare ?
da pannello di controllo->op. pianificate selezioni il .exe e il timer

leon84
04-06-2004, 14:48
Originariamente inviato da LukeHack
da pannello di controllo->op. pianificate selezioni il .exe e il timer

No scusa forse mi sono spiegato male .... come dire a windows di connettersi e disconnettersi in modo pianificato non avviare il mio programma ....

LukeHack
04-06-2004, 16:00
Originariamente inviato da leon84
No scusa forse mi sono spiegato male .... come dire a windows di connettersi e disconnettersi in modo pianificato non avviare il mio programma ....
creati un .ras o .lnk della tua connessione (per es. tiscali.ras), metti ad ON l'autoconnection manager e dalla connessione dechecka "richiedi numero e user id"...
fai puntare il .ras (ma basta anche una pagina html a questo punto,tanto l'autoconnection manager ti invoca da solo il .ras) da op.pianificate

LukeHack
04-06-2004, 16:03
Originariamente inviato da cionci
Ecco qua:
quindi con questo posso mandare allegati giusto? mi basta invocare la funzione Base64Encode(const string &data) ?
se è cosi MOLTO LOLLOSO grazie

:oink: :oink:

cionci
04-06-2004, 16:39
Questo serve per codificare username e password...
Se non sbaglio la codifica UU usata per gli attachment è formata da:
/*riga vuota*/
begin 666 nomedelfile
/*file codificato in base64*/
`
end
/*riga vuota*/

Comunque credo sia meglio cercare qualcosa di preciso ;)

NA01
04-06-2004, 19:52
Originariamente inviato da LukeHack
si ma qual'è il tuo provider? fastweb? se cosi usa smtp.fastwebnet.it
e stai aposto! (per mandare email)
certo, certo
uso tutti e due, con email.it basta attivare l'autenticazione in uscita e funzia tutto ;)

ciao

LukeHack
04-06-2004, 20:37
Originariamente inviato da cionci
Questo serve per codificare username e password...
Se non sbaglio la codifica UU usata per gli attachment è formata da:
/*riga vuota*/
begin 666 nomedelfile
/*file codificato in base64*/
`
end
/*riga vuota*/

Comunque credo sia meglio cercare qualcosa di preciso ;)
appunto,se il tuo codice esegue la codifica64, allora è possibile passare alla funzione il puntatore ad una stringa,risultato di una fscanf di un file (attachment), ed ottenerne la codifica no?

cionci
05-06-2004, 02:49
Sì, ma non sono sicuro che il formato sia precisamente questo...sarebbe meglio verificare...

NA01
05-06-2004, 06:55
Originariamente inviato da cionci
Sì, ma non sono sicuro che il formato sia precisamente questo...sarebbe meglio verificare...
una prova dovrebbe bastare, se ho tempo oggi pomeriggio provo

ciao e grazie