Envoyé un Mail en C sous linux

Envoyé un Mail en C sous linux - C++ - Programmation

Marsh Posté le 01-04-2003 à 11:51:40    

alors voila, il me fodrait un programme qui fonctionne sous linux, et en language c, ki me permette d'envoyer un mail.
 
pour l'instant, g sa, mais c'est du c++ et pour windows.
 
alors si kk auraot la gentillesse de me le convertir, ou alors de me foler un programme meme completement different mais qui fasse ce ke je souhaite, je serait trop content.
 

Code :
  1. #include <winsock.h>
  2.   #include <iostream.h>
  3.   #include <string.h>
  4.  
  5.   SOCKET to_server_socket = 0;
  6.   char     server_name[100];
  7.   int port             = 25;
  8.  
  9.   char destinataire[120] = "RCPT To: <";
  10.   char sender[120] = "MAIL From: <";
  11.   char exp[100], dest[100];
  12.   char sujet[50];
  13.   char message[1000];
  14.   char body[1100] = "Subject: ";
  15.  
  16.   void bcopy( void * source, void * destination, int size )
  17.   {
  18.          char * src = ( char * ) source;
  19.          char * dst = ( char * ) destination;
  20.    
  21.          for( int i=0; i<size; i++ )
  22.             dst[i] = src[i];
  23.   }
  24.  
  25.   void bzero( void * destination, int size )
  26.   {
  27.          char * dst = ( char * ) destination;
  28.    
  29.          for( int i=0; i<size; i++ )
  30.             dst[i] = 0x00;
  31.   }
  32.  
  33.   void Process( char * buffer )
  34.   {
  35.          Sleep( 1000 );
  36.          cerr << "Envoye   < " << buffer << endl;
  37.          int    size     = strlen( buffer );
  38.          int    retVal = send( to_server_socket, buffer, size, 0 );
  39.    
  40.          char buf[ 1024 ];
  41.          buf[0] = 0x00;
  42.          while( !buf[0] )
  43.             int yeah = recv( to_server_socket, buf, 1024, 0 );
  44.          cerr << "Recu   > " << buf << endl << endl;
  45.   }
  46.  
  47.   int main( int argc, char *argv[] )
  48.   {
  49.          int             not            = 0;
  50.          unsigned long ioctl_blocking = 1;
  51.    
  52.          cout<<"Entrez le nom du serveur smtp ou son ip\n";
  53.          cin>>server_name;
  54.          cout<<"Entrez l'adresse email de l'expediteur\n";
  55.          cin>>exp;
  56.          cout<<"\nEntrez l'adresse email du destinataire\n";
  57.          cin>>dest;
  58.          cout<<"\nEntrez le sujet du mail\n";
  59.          cin>>sujet;
  60.          cout<<"\nEntrez votre message\n";
  61.          cin>>message;
  62.    
  63.          strcat(sender,exp);
  64.          strcat(sender,">\r\n" );
  65.          strcat(destinataire,dest);
  66.          strcat(destinataire,">\r\n" );
  67.          strcat(body,sujet);
  68.          strcat(body," \r\n\r\n " );
  69.          strcat(body,message);
  70.          strcat(body," \r\n.\r\n" );
  71.    
  72.          WSADATA wsaData;
  73.          if( int err = WSAStartup( 0x0101, &wsaData ) )
  74.          {
  75.               cerr << "WSAStartup failed... Error: " << err << endl;
  76.               exit( -1 );
  77.          }
  78.    
  79.    
  80.          struct sockaddr_in  serverSockAddr;    // addresse de la socket
  81.          struct hostent  * serverHostEnt;    // description du host serveur
  82.          long                hostAddr;          // addr du serveur
  83.    
  84.          bzero( &serverSockAddr, sizeof( serverSockAddr ) );     // initialise a zero serverSockAddr
  85.          // converti l'adresse ip 9.100.1.1 en entier long
  86.          hostAddr = inet_addr( server_name );
  87.    
  88.          if( ( long ) hostAddr != ( long ) -1 )                 
  89.               bcopy( &hostAddr, &serverSockAddr.sin_addr, sizeof( hostAddr ) );
  90.          else                                                   // si on a donne un nom
  91.          {
  92.               serverHostEnt = gethostbyname( server_name );
  93.               if ( serverHostEnt == NULL )
  94.               {
  95.                  cerr << "echec gethost" << endl;
  96.                  exit( 0 );
  97.               }
  98.               bcopy( serverHostEnt->h_addr, &serverSockAddr.sin_addr, serverHostEnt->h_length );
  99.          }
  100.    
  101.          serverSockAddr.sin_port = htons( port );        // host to network port
  102.          serverSockAddr.sin_family = AF_INET;            // AF_*** : INET=internet
  103.          // creation de la socket
  104.    
  105.          to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );
  106.          if ( to_server_socket < 0)
  107.          {
  108.               cerr << "echec creation socket client" << endl;
  109.               exit( 0 );
  110.          }
  111.    
  112.          setsockopt(to_server_socket, SOL_SOCKET, SO_DONTLINGER, (char *) ¬, sizeof(not));
  113.    
  114.    
  115.          // requete de connexion
  116.          if( connect( to_server_socket, ( struct sockaddr * ) &serverSockAddr, 
  117.                                               sizeof( serverSockAddr ) ) < 0 )
  118.          {
  119.               cerr << "echec demande de connection" << endl;
  120.               exit( 0 );
  121.          }
  122.    
  123.          ioctlsocket ( to_server_socket, FIONBIO, &ioctl_blocking );
  124.    
  125.          char buf[ 1024 ];
  126.          buf[0] = 0x00;
  127.          while( !buf[0] )
  128.             int yeah = recv( to_server_socket, buf, 1024, 0 );
  129.          cerr << "Receive > " << buf << endl << endl;
  130.    
  131.          Process( "EHLO Toto\r\n" );
  132.          Process( sender );  // mail de l'expediteur
  133.          Process( destinataire );    // mail du destinataire
  134.          Process( "DATA\r\n" );
  135.          Process( body );
  136.          Process( "QUIT\r\n" );
  137.    
  138.          /* fermeture de la connection */
  139.          shutdown( to_server_socket, 2 );
  140.          
  141.          return( closesocket( to_server_socket ) );
  142.   }


 
merci d'avance


---------------
Team officielle JackyPC. com :sol:
Reply

Marsh Posté le 01-04-2003 à 11:51:40   

Reply

Marsh Posté le 01-04-2003 à 11:54:57    

tu vires ca :
 

Citation :

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


 
remplace les << par les printfs adequat et voila

Reply

Marsh Posté le 01-04-2003 à 12:16:20    

Voici quelques observations sur le passage Windows->Linux. Pour le passage C++ -> C, il n'y a pas grand chose à faire.
 

Code :
  1. #include <winsock.h> // a supprimer... il y a d'autres headers pour linux
  2.   #include <iostream.h>
  3.   #include <string.h>
  4.  
  5.   SOCKET to_server_socket = 0; // tu remplaces SOCKET par int
  6.   char     server_name[100];
  7.   int port             = 25;
  8.  
  9.   char destinataire[120] = "RCPT To: <";
  10.   char sender[120] = "MAIL From: <";
  11.   char exp[100], dest[100];
  12.   char sujet[50];
  13.   char message[1000];
  14.   char body[1100] = "Subject: ";
  15.  
  16. /* A quoi elle sert cette fonction ??? */
  17. /* Il y a la fonction memcpy qui permet de faire le même chose */
  18.   void bcopy( void * source, void * destination, int size )
  19.   {
  20.          char * src = ( char * ) source;
  21.          char * dst = ( char * ) destination;
  22.    
  23.          for( int i=0; i<size; i++ )
  24.             dst[i] = src[i];
  25.   }
  26.  
  27. /* Pareil qu'au dessus. memset existe ! */
  28.   void bzero( void * destination, int size )
  29.   {
  30.          char * dst = ( char * ) destination;
  31.    
  32.          for( int i=0; i<size; i++ )
  33.             dst[i] = 0x00;
  34.   }
  35.  
  36.   void Process( char * buffer )
  37.   {
  38.          Sleep( 1000 );  /* Sleep() est une fonction Windows. Je ne sais pas comment la "traduire". Mais est-elle réellement utile ? */
  39.          cerr << "Envoye   < " << buffer << endl;
  40.          int    size     = strlen( buffer );
  41.          int    retVal = send( to_server_socket, buffer, size, 0 );
  42.    
  43.          char buf[ 1024 ];
  44.          buf[0] = 0x00;
  45.          while( !buf[0] )
  46.             int yeah = recv( to_server_socket, buf, 1024, 0 );
  47.          cerr << "Recu   > " << buf << endl << endl;
  48.   }
  49.  
  50.   int main( int argc, char *argv[] )
  51.   {
  52.          int             not            = 0;
  53.          unsigned long ioctl_blocking = 1;
  54.    
  55.          cout<<"Entrez le nom du serveur smtp ou son ip\n";
  56.          cin>>server_name;
  57.          cout<<"Entrez l'adresse email de l'expediteur\n";
  58.          cin>>exp;
  59.          cout<<"\nEntrez l'adresse email du destinataire\n";
  60.          cin>>dest;
  61.          cout<<"\nEntrez le sujet du mail\n";
  62.          cin>>sujet;
  63.          cout<<"\nEntrez votre message\n";
  64.          cin>>message;
  65.    
  66.          strcat(sender,exp);
  67.          strcat(sender,">\r\n" );
  68.          strcat(destinataire,dest);
  69.          strcat(destinataire,">\r\n" );
  70.          strcat(body,sujet);
  71.          strcat(body," \r\n\r\n " );
  72.          strcat(body,message);
  73.          strcat(body," \r\n.\r\n" );
  74.    
  75. /* A supprimer... c'est du code spécifique à Windows */
  76.          WSADATA wsaData;
  77.          if( int err = WSAStartup( 0x0101, &wsaData ) )
  78.          {
  79.               cerr << "WSAStartup failed... Error: " << err << endl;
  80.               exit( -1 );
  81.          }
  82. /************/
  83.    
  84.          struct sockaddr_in  serverSockAddr;    // addresse de la socket
  85.          struct hostent  * serverHostEnt;    // description du host serveur
  86.          long                hostAddr;          // addr du serveur
  87.    
  88.          bzero( &serverSockAddr, sizeof( serverSockAddr ) );     // initialise a zero serverSockAddr
  89.          // converti l'adresse ip 9.100.1.1 en entier long
  90.          hostAddr = inet_addr( server_name );
  91.    
  92.          if( ( long ) hostAddr != ( long ) -1 )                 
  93.               bcopy( &hostAddr, &serverSockAddr.sin_addr, sizeof( hostAddr ) );
  94.          else                                                   // si on a donne un nom
  95.          {
  96.               serverHostEnt = gethostbyname( server_name );
  97.               if ( serverHostEnt == NULL )
  98.               {
  99.                  cerr << "echec gethost" << endl;
  100.                  exit( 0 );
  101.               }
  102.               bcopy( serverHostEnt->h_addr, &serverSockAddr.sin_addr, serverHostEnt->h_length );
  103.          }
  104.    
  105.          serverSockAddr.sin_port = htons( port );        // host to network port
  106.          serverSockAddr.sin_family = AF_INET;            // AF_*** : INET=internet
  107.          // creation de la socket
  108.    
  109.          to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );
  110.          if ( to_server_socket < 0)
  111.          {
  112.               cerr << "echec creation socket client" << endl;
  113.               exit( 0 );
  114.          }
  115.    
  116.          setsockopt(to_server_socket, SOL_SOCKET, SO_DONTLINGER, (char *) ¬, sizeof(not));
  117.    
  118.    
  119.          // requete de connexion
  120.          if( connect( to_server_socket, ( struct sockaddr * ) &serverSockAddr, 
  121.                                               sizeof( serverSockAddr ) ) < 0 )
  122.          {
  123.               cerr << "echec demande de connection" << endl;
  124.               exit( 0 );
  125.          }
  126.    
  127.          ioctlsocket ( to_server_socket, FIONBIO, &ioctl_blocking ); // ioctlsocket ne semble pas exister sous Linux - ici il passe en mode non bloquant
  128.    
  129.          char buf[ 1024 ];
  130.          buf[0] = 0x00;
  131.          while( !buf[0] )
  132.             int yeah = recv( to_server_socket, buf, 1024, 0 );
  133.          cerr << "Receive > " << buf << endl << endl;
  134.    
  135.          Process( "EHLO Toto\r\n" );
  136.          Process( sender );  // mail de l'expediteur
  137.          Process( destinataire );    // mail du destinataire
  138.          Process( "DATA\r\n" );
  139.          Process( body );
  140.          Process( "QUIT\r\n" );
  141.    
  142.          /* fermeture de la connection */
  143.          shutdown( to_server_socket, 2 );
  144.          
  145.          return( closesocket( to_server_socket ) );
  146.   }


 
Par contre, il est vrai que le code est pas très joli. Je serais toi, j'essaierais de trouver autre chose voire de le réecrire. Ce n'est pas très compliqué, il faut juste quelques connaissances sur les sockets et regarder un peu le protocole SMTP.


---------------
each day I don't die is cheating
Reply

Marsh Posté le 01-04-2003 à 12:35:29    

Ou alors tu utilises une lib qui fait déjà ça...


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 01-04-2003 à 13:53:00    

c koi cette lib en question ?
 
je ne connait rien au socket ni au protocole smtp ?
 
ya pas un pros ki peut me reecrire le code ?


---------------
Team officielle JackyPC. com :sol:
Reply

Marsh Posté le 01-04-2003 à 13:55:59    

nexosenz a écrit :


ya pas un pros ki peut me reecrire le code ?


[:meganne] non.

Reply

Marsh Posté le 01-04-2003 à 14:00:04    

nexosenz a écrit :


ya pas un pros ki peut me reecrire le code ?


[:ddr555]


---------------
get amaroK plugin
Reply

Marsh Posté le 01-04-2003 à 14:00:21    

nexosenz a écrit :

c koi cette lib en question ?
 
je ne connait rien au socket ni au protocole smtp ?
 
ya pas un pros ki peut me reecrire le code ?


100 balles et un mars aussi ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-04-2003 à 14:29:12    

nexosenz a écrit :

c koi cette lib en question ?
 
je ne connait rien au socket ni au protocole smtp ?
 
ya pas un pros ki peut me reecrire le code ?

http://www.google.com/images/logo.gif http://images.freshmeat.net/logo.gif


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 01-04-2003 à 16:26:40    

vous ete cool ici c super.
 
bon jretourne sur mon forum


---------------
Team officielle JackyPC. com :sol:
Reply

Marsh Posté le 01-04-2003 à 16:26:40   

Reply

Marsh Posté le 01-04-2003 à 16:31:34    

En fait je crois que tu es encore plus boulet que tu en as l'air. Dis-moi, tu veux juste envoyer un mail, n'est-ce pas ? Et ce, sans forcément imposer le serveur SMTP, hmmm ?
Ignorerais-tu donc que sous unix on n'a pas besoin de SMTP pour envoyer un mail et qu'on peut se contenter d'appeler sendmail ou mailx ?


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 01-04-2003 à 16:37:56    

Jar Jar a écrit :

En fait je crois que tu es encore plus boulet que tu en as l'air. Dis-moi, tu veux juste envoyer un mail, n'est-ce pas ? Et ce, sans forcément imposer le serveur SMTP, hmmm ?
Ignorerais-tu donc que sous unix on n'a pas besoin de SMTP pour envoyer un mail et qu'on peut se contenter d'appeler sendmail ou mailx ?


 
Tiens, c'est amusant ça. Un des premiers articles dans LMF à propos des failles de sécurité reposait justement sur "pourquoi est-ce que c'est pas simple d'écrire un programme 'sûr' qui appelle directement sendmail".
Ceci dit, c'est vrai que ca reste une méthode simple.

Reply

Marsh Posté le 01-04-2003 à 16:39:22    

tiens en passant, tu pourrai remplacer "envoyé" par "envoyer" dans le titre du topic ?
Ok, on fait tous des fotes (moi le premier), mais dans les titres de topics qui sont sous mon nez ça me ... :D

Reply

Marsh Posté le 01-04-2003 à 16:41:40    

sowhatin22 a écrit :

Tiens, c'est amusant ça. Un des premiers articles dans LMF à propos des failles de sécurité reposait justement sur "pourquoi est-ce que c'est pas simple d'écrire un programme 'sûr' qui appelle directement sendmail".
Ceci dit, c'est vrai que ca reste une méthode simple.

C'est bizarre ça, j'aurais pensé que ce qui compte, c'est la sécurité de l'exécutable sendmail lui-même (vu qu'il est SUID root). Ou alors je ne comprends pas bien ce que tu veux dire par "sûr" dans ce cas.
Enfin sans passer par sendmail, on peut utiliser mailx, ce qui est quand même carrément trivial.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 01-04-2003 à 16:59:17    

Jar Jar a écrit :

C'est bizarre ça, j'aurais pensé que ce qui compte, c'est la sécurité de l'exécutable sendmail lui-même (vu qu'il est SUID root). Ou alors je ne comprends pas bien ce que tu veux dire par "sûr" dans ce cas.
Enfin sans passer par sendmail, on peut utiliser mailx, ce qui est quand même carrément trivial.


il faudrait relire l'article pour plus de tétails. Sendmail servait d'exemple parce souvent on voudrait pouvoir un mail de notification  depuis un programme, et que c'est un moyen assez simple. Le probleme, c'est que c'est souvent fait avec la fonction 'exec' car on utilise le binaire tel quel et non pas une librairie. Les problèmes de sécurité venaient vienne de cet appel ( check de l'uid, de la cohérence des variables d'environement, du binaire qui est réellement appelé, etc...).

Reply

Marsh Posté le 01-04-2003 à 17:25:55    

c une blague bzero/bcopy réécrit à la main?
(et <iostream.h>, c'est tellement mieux de fair eun programme C et de remplacer les printf par de cout, pour pouvoir dire "je fais du C++", vive strcat et prions pour que body/dest/exp/[char*] soit assez grand)


Message édité par Taz le 01-04-2003 à 17:29:58
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed