[c/linux] envoyer un message par mail

Description

C'est fait de la manière la plus simple qui soit,
avec un minimum de variables déclarées.

Si quelqu'un s' attend à un client mail complet, qu'il passe son chemin
ou qu'il en installe un! Pour les autres, ce code constituera l' ossature
d'une application. C'est une des raisons pour lesquelles je le poste.
L' autre raison étant bien entendu de présenter brièvement le protocole SMTP
à ceux qui s'y intéressent.

A vous de l' étoffer en déclarant 60 variables, pour le FROM, le TO, etc...
Parce qu'il faut bien reconnaitre que tout est en dur!

Aussi, le code est du C -toujours par souci de flexibilité- pour
sa facilité de passage vers le C++. Qui peut le moins peut le plus.

Source / Exemple :


// Envoyer un mail
// gcc -Wall -o mail mail.c

#include <stdio.h>	// pour puts()
#include <string.h>	// pour bzero() bcopy() strlen()

//includes réseau
#include <unistd.h>	// pour close()
#include <netdb.h>	// pour gethostbyname()
#include <arpa/inet.h>  // pour sockaddr_in

int sk = -1;		//le descripteur du socket

char serveur[] = "smtp.wanadoo.fr";

char lemail[] = "HELO wanadoo.fr\r\n"
		"MAIL FROM: <blabla@orange.fr>\n"
		"RCPT TO: <truc@truc.fr>\n"
		"DATA\r\n"
		"Subject: le mur et les oreilles\r\n"
 		"FROM: François <blabla@orange.fr>\r\n"
		"TO: Segolene <truc@unautre.fr>\r\n"
		"Bijour\r\n"
		"petit message\r\n"
		".\r\n"
		"QUIT\r\n\r\n";

//Déclaration des Prototypes de fonctions
unsigned short init_socket();
void recevoir_reponse();

int main (int argc, char *argv[])
{

	if (init_socket())
	{
	send(sk, lemail, strlen(lemail)-1, 0);
	recevoir_reponse(); //fermera le socket.
	}

	return 0;
}

unsigned short init_socket()
{
	struct sockaddr_in serveurSockAddr;	// addresse
	struct hostent *serveurHostEnt;		// description host serveur
	unsigned long hostAddr;			// addr du serveur

	bzero(&serveurSockAddr,sizeof(serveurSockAddr));
	hostAddr = inet_addr(serveur); // convertit l'adresse ip en entier long

	if ( (long)hostAddr != (long)-1)
		bcopy(&hostAddr,&serveurSockAddr.sin_addr,sizeof(hostAddr));
	else  // on a donné un nom, pas une IP
	{
 		serveurHostEnt = gethostbyname(serveur);
		if (serveurHostEnt == NULL)
  		{
			puts("probleme gethost");
			return 0;
		}
 		bcopy(serveurHostEnt->h_addr,&serveurSockAddr.sin_addr, serveurHostEnt->h_length);
	}

	serveurSockAddr.sin_port = htons(25); //port 25 pour SMTP
	serveurSockAddr.sin_family = AF_INET;

	if ( (sk = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		puts("Impossible de creer le socket");
		return 0;
 	}

	if(connect(sk,(struct sockaddr *)&serveurSockAddr, sizeof(serveurSockAddr)) < 0)
	{
		puts("probleme sur connect()");
		return 0;
	}
	else
	{
		printf("Connecté au serveur %s\n",serveur);
		return 1;
	}
}

void recevoir_reponse()
{
	puts("En attente de la reponse ...\n");
	char  tempBuffer[1024];
	int retval;

	while(1)
	{
	    retval = recv(sk, tempBuffer, sizeof(tempBuffer)-1, 0);
	    if (retval==0)
	    { 
			shutdown(sk,2); //ferme le socket
			close(sk);
			puts("Socket fermé.");
	        break;
	    }
	    else if (retval == -1)
	    {
	        puts("Erreur pendant la reception");
	    }
	    else
	    {
	        tempBuffer[retval] = 0;
	        puts(tempBuffer);
	    }
	}
}

Conclusion :


Note pour les nouveaux Linuxiens:

Pour compiler "à la main" dans une console c'est:
$ cd repertoire
$ gcc -Wall -o mail mail.c

Puis pour exécuter le prog c'est:
$ ./mail
En sachant que double-cliquer sur l' exécutable marche aussi.

Note2: si vous avez des problèmes avec les accents dans la console, faut voir
si vos "Locales" sont bien configurées pour le français.

La conversion vers le Win32 est ultra simple, je modifie le code
à cet effet si quelqu'un le demande. Deux ou trois directives pré-processeur
et le binz devient portable à 100%, sans danser la java. De toute façon Java
est écrit en langage C ...

Le main() appelle 2 routines:
- init_socket() qui crée un socket et se connecte sur le port 25,
- recevoir_reponse() qui lit les paquets entrants et les affiche sur la sortie standard.

Il n' y a effectivement pas de conversation protocolaire entre le client et le serveur,
puisque le prog envoie un string complet au serveur sans écouter ce que lui répond le
serveur, à la manière d'une requête HTTP! C'est du brut, du simple et du pas compliqué.

J'espère que vous apprécierez.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.