forwarder d'email
Le principe de ce petit programme est de prendre tous les messages d'un compte POP et de les renvoyer vers une autre adresse.
l'option '-d' passée en ligne de commande permet de supprimer les mails
du compte pop.
Il y a donc pas mal de paramètres à passer:
- smtp_name: nom du serveur smtp
- smtp_from: ne sert pas a grand chose, mais c'est indispensable, vous pouvez mettre ici votre adresse sur le compte pop
- smtp_to: l'adresse a laquelle vous voulez faire suivre les mails récupérer
- pop_name: le nom du serveur pop3
- user: votre nom d'utilisateur sur le serveur pop3
- pass: le mot de passe qui va avec
#include <arpa/telnet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PACKET_SIZE 1024
#define DEBUG 1
void appli ( void ) ;
int writen(int fd, char *ptr, int n);
int readn(int fd, char *ptr, int n);
char *smtp_name = "SMTP SERVER";
unsigned short smtp_port = 25;
char smtp_from[] = "mail from: <ADDRESSE DE L ENVOYEUR>\n";
char smtp_to[] = "rcpt to: <ADDRESSE DESTINATAIRE>\n";
char *pop_name = "SERVER POP";
int pop_port = 110;
char *user= "USERNAME POP";
char *pass= "PASSWORD";
int delete_msg = 0;
int to_pop_socket = -1;
int to_smtp_socket = -1;
int main (int argc, char *argv[])
{
struct sockaddr_in popSockAddr; /* addresse de la socket */
struct hostent *popHostEnt; /* description du host serveur */
unsigned long popAddr; /* addr du serveur */
struct sockaddr_in smtpSockAddr; /* addresse de la socket */
struct hostent *smtpHostEnt; /* description du host serveur */
unsigned long smtpAddr; /* addr du serveur */
long status;
char buffer[PACKET_SIZE+1];
int optval = 1;
if ( argc == 2 )
if ( ! strncmp(argv[1], "-d", 2) )
delete_msg = 1;
bzero(&popSockAddr,sizeof(popSockAddr));/*init a zero popSockAddr*/
popAddr = inet_addr(pop_name); /* converti l'adress ip 9.100.1.1
en entier long */
bzero(&smtpSockAddr,sizeof(smtpSockAddr));
smtpAddr = inet_addr(smtp_name);
if ( (long)popAddr != (long)-1)
bcopy(&popAddr,&popSockAddr.sin_addr,sizeof(popAddr));
else /* si on a donne un nom */
{
popHostEnt = gethostbyname(pop_name);
if (popHostEnt == NULL)
{
printf("ca chie gethost\n");
exit(0);
}
bcopy(popHostEnt->h_addr,&popSockAddr.sin_addr,popHostEnt->h_length);
}
if ( (long)smtpAddr != (long)-1)
bcopy(&smtpAddr,&smtpSockAddr.sin_addr,sizeof(smtpAddr));
else /* si on a donne un nom */
{
smtpHostEnt = gethostbyname(smtp_name);
if (smtpHostEnt == NULL)
{
printf("ca chie gethost\n");
exit(0);
}
bcopy(smtpHostEnt->h_addr,&smtpSockAddr.sin_addr,smtpHostEnt->h_length);
}
popSockAddr.sin_port = htons(pop_port); /* host to network port */
popSockAddr.sin_family = AF_INET; /* AF_*** : INET=internet */
/* creation de la socket */
smtpSockAddr.sin_port = htons(smtp_port); /* host to network port */
smtpSockAddr.sin_family = AF_INET; /* AF_*** : INET=internet */
/* creation de la socket */
if ( (to_pop_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("ca chie creation socket client\n");
exit(0);
}
if ( (to_smtp_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("ca chie creation socket client\n");
exit(0);
}
/*
if (setsockopt(to_pop_socket,SOL_SOCKET,SO_KEEPALIVE,
(char *)&optval,sizeof(int)) <0)
{
printf("ca chie setsockopt\n");
exit(0);
}
*/
/* requete de connexion */
if(connect(to_pop_socket,(struct sockaddr *)&popSockAddr,
sizeof(popSockAddr))<0)
{
printf("ca chie demande de connection\n");
exit(0);
}
if(connect(to_smtp_socket,(struct sockaddr *)&smtpSockAddr,
sizeof(smtpSockAddr))<0)
{
printf("ca chie demande de connection\n");
exit(0);
}
appli();
/* fermeture de la connection */
shutdown(to_pop_socket,2);
close(to_pop_socket);
shutdown(to_smtp_socket,2);
close(to_smtp_socket);
return 0;
}
int writen(int fd, char *ptr, int n)
{
char *p;
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, retry=0;
nl = n;
bzero(ptr,n);
while ( nl > 0 ) {
nr = read(fd,ptr,nl);
if (nr < 0 ) {
if (errno != EAGAIN) { printf("EAGAIN\n"); exit(1); }
retry++;
usleep(100);
if ( retry >= 5 ) 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);
}
int test_OK(char *buf, int do_exit) {
char *ptr, tmp[PACKET_SIZE+1];
bzero(tmp, PACKET_SIZE+1);
if ((ptr=strstr(buf, "+OK")) == NULL) {
if (DEBUG) printf("%s", buf);
if ( strstr(buf, "-ERR") ) {
printf("ERROR: -->%s<--\n", buf);
exit(1);
}
if (do_exit ) exit(1);
else return 1;
} else {
if (DEBUG) printf("-->%s<--\n",ptr);
while(*ptr != '\n') ptr++ ;
bcopy(ptr+1,tmp,strlen(ptr));
bzero(buf,PACKET_SIZE+1);
bcopy(tmp, buf, strlen(tmp));
}
return 0;
}
int test_250(char *buf) {
char *ptr, tmp[PACKET_SIZE+1];
bzero(tmp, PACKET_SIZE+1);
if ((ptr=strstr(buf, "250 OK")) == NULL) {
if (DEBUG) printf("ERROR: %s", buf);
exit(1);
} else {
if (DEBUG) printf("-->%s<--\n",ptr);
while(*ptr != '\n') ptr++ ;
bcopy(ptr+1,tmp,strlen(ptr));
bzero(buf,PACKET_SIZE+1);
bcopy(tmp, buf, strlen(tmp));
}
return 0;
}
void begin_smtp( void ) {
char buf[PACKET_SIZE+1];
readn(to_smtp_socket,buf,PACKET_SIZE);
printf(buf);
}
void begin_mail( void ) {
char buf[PACKET_SIZE+1];
sleep(1);
writen(to_smtp_socket,smtp_from,strlen(smtp_from));
printf(smtp_from);
readn(to_smtp_socket,buf,PACKET_SIZE);
test_250(buf);
writen(to_smtp_socket,smtp_to,strlen(smtp_to));
printf(smtp_to);
readn(to_smtp_socket,buf,PACKET_SIZE);
test_250(buf);
writen(to_smtp_socket,"data\n",6);
printf(buf);
readn(to_smtp_socket,buf,PACKET_SIZE);
printf(buf);
}
void appli ( void )
{
unsigned char bufw[PACKET_SIZE+1];
unsigned char bufr[PACKET_SIZE+1];
unsigned char list[PACKET_SIZE+1];
int n, msg, index, retry = 4;
begin_smtp();
bzero(bufw, PACKET_SIZE+1);
bzero(bufr, PACKET_SIZE+1);
do {
n=readn(to_pop_socket,bufr,PACKET_SIZE);
retry--;
} while(test_OK(bufr,retry==0));
//if (strlen(bufr) == 0 ) n=readn(to_pop_socket,bufr,PACKET_SIZE);
if (DEBUG) printf("??? %s ???\n", bufr);
sprintf(bufw,"USER %s\r\n",user);
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
if (DEBUG) printf("USER: ");
test_OK(bufr,1);
sprintf(bufw,"PASS %s\r\n",pass);
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
if (DEBUG) printf("PASS: ");
test_OK(bufr,1);
sprintf(bufw,"LIST\r\n");
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
if (DEBUG) printf("LIST: ");
test_OK(bufr,1);
if (strlen(bufr) == 0 ) n=readn(to_pop_socket,list,PACKET_SIZE);
else bcopy(bufr, list, strlen(bufr) + 1) ;
if (DEBUG) printf(list);
index = 0;
while ( list[index] != '.' ) {
sscanf(&list[index], "%d", &msg);
while(list[index++] != '\n');
sprintf(bufw,"RETR %d\r\n",msg);
if (DEBUG) printf("^[[34m %s^[[30m",bufw);
begin_mail();
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
test_OK(bufr,1);
n=strlen(bufr);
do {
if (strlen(bufr) == 0 ) n=readn(to_pop_socket,bufr, PACKET_SIZE);
writen(to_smtp_socket, bufr, n);
if ( ! strncmp("\r\n.\r\n",&bufr[n-5],5) ) break;
bzero(bufr, PACKET_SIZE+1);
} while ( 1 );
readn(to_smtp_socket,bufr, PACKET_SIZE);
test_250(bufr);
if ( delete_msg ) {
sprintf(bufw,"DELE %d\r\n",msg);
if (DEBUG) printf("^[[34m %s^[[30m",bufw);
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
test_OK(bufr,1);
}
}
sprintf(bufw,"QUIT\r\n");
writen(to_pop_socket,bufw,strlen(bufw));
n=readn(to_pop_socket,bufr,PACKET_SIZE);
test_OK(bufr,0);
}
|