envoie d'un fichier par email avec smtp


Voici un petit code en langage C pour effectuer l'envoie d'un fichier texte par mail.

Il suffit de modifier SERVEUR SMTP, ADDR DESTINATION et c'est parti.

ligne de commande: smc nom_du_fichier

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define DEBUG 0 /* Attention il y des pb si le msg envoye contient des % */

#define PACKET_SIZE  1024

void appli(char *f);
int writen(int fd, char *ptr, int n);
int readn(int fd, char *ptr, int n);

int to_server_socket = -1;
char server_name[] = "SERVEUR SMTP";  /* nom du host du serveur */
int port = 25;
char helo[] = "helo plus.bas\n";
char from[] = "mail from: <nic@salemioche.com>\n";
char to[] = "rcpt to: <ADDR DEST>\n";

char subject[] = "Subject: transfert ";


int main (int argc, char *argv[])
{
    struct sockaddr_in serverSockAddr;    /* addresse de la socket */
    struct hostent *serverHostEnt;        /* description du host serveur */
    unsigned long hostAddr;                       /* addr du serveur */
    char *filename;

    if ( argc == 2 ) filename = argv[1];
    else filename = NULL; /* use stdin */

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

    if ( (long)hostAddr != (long)-1)
            bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr));
    else                                /* si on a donne un nom  */
    {
            serverHostEnt = gethostbyname(server_name);
            if (serverHostEnt == NULL)
            {
                    printf("probleme gethost\n");
                    exit(0);
            }
            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 */

    if ( (to_server_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
            printf("probleme creation socket client\n");
            exit(0);
    }

    /* requete de connexion */
    if(connect(to_server_socket,(struct sockaddr *)&serverSockAddr,
               sizeof(serverSockAddr))<0)
    {
            printf("probleme demande de connection\n");
            exit(0);
    }
    appli(filename);

    /* fermeture de la connection */
    shutdown(to_server_socket,2);
    close(to_server_socket);
    return 0;
}

void appli (char *filename) {
char buf[PACKET_SIZE+1], *ptr;
FILE *bulk;
int nb;

        if (filename == NULL) {
          bulk = stdin;
        } else {
            if ( ( bulk = fopen(filename,"rb")) == NULL ) {
                    printf ( "can't open file to read\n" );
                    exit(1);
            }
        }
        buf[0] = 0x00;
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);
        writen(to_server_socket,helo,strlen(helo));
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);
        writen(to_server_socket,from,strlen(from));
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);
        writen(to_server_socket,to,strlen(to));
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);
        writen(to_server_socket,"data\n",6);
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);

        sprintf(buf,"%s %s\n\n", subject,
                              (( filename == NULL ) ? "STDIN" : filename ) );
        writen(to_server_socket,buf,strlen(buf));
/* the file */
        while ( !feof(bulk) ) {
          bzero(buf, PACKET_SIZE+1);
          nb = fread(buf,sizeof(char), PACKET_SIZE, bulk);
          buf[nb] = 0x00;
          while ( (ptr = strstr(buf,"\r\n.\r\n") ) != NULL ) *(ptr+3) = '.';
          writen(to_server_socket,buf,nb);
          if (DEBUG) printf(buf);
        }

        writen(to_server_socket,"\r\n.\r\n",5);
        readn(to_server_socket,buf,PACKET_SIZE);
        printf(buf);


        fclose(bulk);
}

int writen(int fd, char *ptr, int n)
{

int nl, nw;
        nl = n;
        while ( nl > 0 ) {
                nw = write(fd, ptr, nl);
                if ( nw <= 0 )
                        return nw;     /*error*/
                nl -= nw;
                ptr += nw;
        }
        return (n-nl);
}


int readn(int fd, char *ptr, int n){
int nl, nr;

        nl = n;
        while ( nl > 0 ) {
                nr = read(fd,ptr,nl);
                if (nr < 0 )
                        return nr;     /*error*/
                else
                        if ( nr == 0 )
                                break;
                nl -= nr;
                ptr += nr;
                if ( *(ptr-2) == '\r' &&  *(ptr-1) == '\n' )
                  break;
        }
        *ptr = 0x00;
        return (n-nl);
}