/*
* Enviador de cartas personalizadas
*
* nitr0us [nitrousenador.at.gmail.dot.com]
* 09/08/06
*
* Compilacion y ejecucion:
* [COMPILACION]
* $gcc mailer.c -o mailer
* [EJECUCION_EJEMPLO]
* $./mailer emails.txt carta.html fuente@company.com "Este es el asunto" mail.mysmtpserver.com
*
* NOTAS:
* + El archivo de emails debe tener en cada linea una direccion de correo o una direccion de correo y nombre separado por coma.
* Ejemplo: foobar@chiapas.gob.mx,Lic. Alma Madero
* + En la carta en HTML, debe estar la cadena definida en la constante NOMBRE justo donde quiere sustituirse por el nombre de la persona.
* Ejemplo: "
Hola #NOMBRE#, le invito a...
* Resultado: Hola Lic. Alma Madero, le invito a...
*
* !!! EL AUTOR NO SE HACE RESPONSABLE DEL USO QUE PUEDA TENER ESTE CÓDIGO POR TERCEROS !!!
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NOMBRE "#NOMBRE#"
#ifndef IPPORT_SMTP
#define IPPORT_SMTP 25
#endif
int EnviaCarta(int, const char *, const char *, const char *, const char *, const char *);
void header()
{
printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n");
printf("*-*- Enviador de cartas personalizadas -*-*\n");
printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n");
printf("*-*-*-*-*-*-*-* nitr0us [nitrousenador.at.gmail.dot.com] *-*-*-*-*-*-*-*\n");
printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n\n");
}
int main(int argc, char **argv)
{
char *cartaptr, *nombre, *tmpptr, linea[256], lineatmp[256], emaildestino[128];
int fdcarta, sfd, connombre = 1;
unsigned int total = 0, cont = 0;
FILE *fpmails;
struct sockaddr_in mailserver;
struct hostent *hostinfo;
struct stat fileinfo;
if(argc != 6){
header();
fprintf(stderr, "Forma de Uso:\n%s \n", argv[0]);
exit(EXIT_SUCCESS);
}
if((fpmails = fopen(argv[1], "r")) == NULL){
perror(argv[1]);
exit(EXIT_FAILURE);
}
if((fdcarta = open(argv[2], O_RDONLY)) == -1){
perror(argv[2]);
fclose(fpmails);
exit(EXIT_FAILURE);
}
if((hostinfo = gethostbyname(argv[5])) == NULL){
herror("gethostbyname()");
close(fdcarta);
fclose(fpmails);
exit(EXIT_FAILURE);
}
if(fstat(fdcarta, &fileinfo) == -1){
perror("fstat()");
close(fdcarta);
fclose(fpmails);
exit(EXIT_FAILURE);
}
if((cartaptr = (char *) mmap(0, fileinfo.st_size, PROT_READ, MAP_SHARED, fdcarta, 0)) == (void *)-1){
perror("mmap()");
close(fdcarta);
fclose(fpmails);
exit(EXIT_FAILURE);
}
char carta_enviar[fileinfo.st_size + 128], cartatmp[fileinfo.st_size + 128];
memset(&mailserver, 0x00, sizeof(mailserver));
mailserver.sin_family = AF_INET;
mailserver.sin_port = htons(IPPORT_SMTP);
mailserver.sin_addr = *((struct in_addr *)hostinfo->h_addr);
header();
printf("Enviando email a:\n");
while(fgets(linea, 256, fpmails)){
if(isspace((int) linea[0]))
continue;
memset(lineatmp, 0x00, 256);
memset(emaildestino, 0x00, 128);
memset(cartatmp, 0x00, fileinfo.st_size + 128);
memset(carta_enviar, 0x00, fileinfo.st_size + 128);
/* Parseo de mails y nombres */
nombre = strchr(linea, (int) ',');
if(nombre == NULL)
connombre = 0;
else{
connombre = 1;
nombre++; // Avanzar la coma (,)
tmpptr = nombre;
while(*tmpptr != '\n' && *tmpptr != '\r') tmpptr++;
*tmpptr = '\0';
}
if(connombre)
strncpy(emaildestino, strtok(linea, ","), 127);
else{
strncpy(emaildestino, linea, 127);
tmpptr = emaildestino;
while(*tmpptr != '\n' && *tmpptr != '\r') tmpptr++;
*tmpptr = '\0';
}
/* Parseo de mails y nombres */
/* Construccion de la carta */
if(strstr(cartaptr, NOMBRE) == NULL){
fprintf(stderr, "No se encontro: %s en el archivo %s... Saliendo\n", NOMBRE, argv[2]);
close(fdcarta);
fclose(fpmails);
exit(EXIT_FAILURE);
}
strncpy(cartatmp, cartaptr, fileinfo.st_size);
tmpptr = strtok(cartatmp, NOMBRE);
strcpy(carta_enviar, tmpptr);
if(connombre)
strcat(carta_enviar, nombre);
tmpptr = strstr(cartaptr, NOMBRE) + strlen(NOMBRE);
strcat(carta_enviar, tmpptr);
/* Construccion de la carta */
printf("%40s\t", emaildestino);
if((sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1){
perror("socket()");
fclose(fpmails);
munmap(cartaptr, fileinfo.st_size);
exit(EXIT_FAILURE);
}
if(connect(sfd, (struct sockaddr *)&mailserver, sizeof(mailserver)) == -1){
perror("connect()");
fclose(fpmails);
munmap(cartaptr, fileinfo.st_size);
exit(EXIT_FAILURE);
}
if(EnviaCarta(sfd, emaildestino, argv[3], argv[4], carta_enviar, nombre)){
printf("[OK]\n");
cont++;
}
else
printf("[FALLO]\n");
total++;
close(sfd);
sleep(1);
}
printf("\nProceso terminado. Enviados %d emails correctamente de %d.\n\n", cont, total);
close(fdcarta);
fclose(fpmails);
munmap(cartaptr, fileinfo.st_size);
return EXIT_SUCCESS;
}
int EnviaCarta(int sfd, const char *para, const char *de, const char *asunto, const char *carta, const char *nombre)
{
char sendbuff[strlen(carta) + 512], recvbuff[256];
fd_set canread;
struct timeval tv;
tv.tv_sec = 1; // Segundo para esperar el banner
tv.tv_usec = 0;
memset(sendbuff, 0x00, strlen(carta) + 512);
memset(recvbuff, 0x00, 256);
do{
FD_ZERO(&canread);
FD_SET(sfd, &canread);
recv(sfd, recvbuff, 255, 0); //Banner
select(sfd + 1, &canread, NULL, NULL, &tv);
} while(FD_ISSET(sfd, &canread));
send(sfd, "helo foo\r\n", strlen("helo foo\r\n"), 0);
recv(sfd, recvbuff, 255, 0);
sprintf(sendbuff, "mail from: %s\r\n", de);
send(sfd, sendbuff, strlen(sendbuff), 0);
recv(sfd, recvbuff, 255, 0);
recvbuff[3] = '\0';
if(strcmp(recvbuff, "250") != 0){
fprintf(stderr, "mail from fallo - Codigo SMTP recibido: %s\n", recvbuff);
return 0;
}
sprintf(sendbuff, "rcpt to: %s\r\n", para);
send(sfd, sendbuff, strlen(sendbuff), 0);
recv(sfd, recvbuff, 255, 0);
recvbuff[3] = '\0';
if(strcmp(recvbuff, "250") != 0){
fprintf(stderr, "rcpt to fallo - Codigo SMTP recibido: %s\n", recvbuff);
return 0;
}
send(sfd, "data\r\n", strlen("data\r\n"), 0);
recv(sfd, recvbuff, 255, 0);
recvbuff[3] = '\0';
if(strcmp(recvbuff, "354") != 0){
fprintf(stderr, "data fallo - Codigo SMTP recibido: %s\n", recvbuff);
return 0;
}
sprintf(sendbuff, "To: %s <%s>\r\nFrom: <%s>\r\nSubject: %s\r\nContent-Type: text/html; charset=ISO-8859-1\r\nMIME-Version: 1.0\r\n\r\n", nombre, para, de, asunto);
send(sfd, sendbuff, strlen(sendbuff), 0);
sprintf(sendbuff, "%s\r\n.\r\n", carta);
send(sfd, sendbuff, strlen(sendbuff), 0);
recv(sfd, recvbuff, 255, 0);
recvbuff[3] = '\0';
if(strcmp(recvbuff, "250") != 0){
fprintf(stderr, "Cuerpo del mensaje fallo - Codigo SMTP recibido: %s\n", recvbuff);
return 0;
}
send(sfd, "quit\r\n", strlen("quit\r\n"), 0);
return 1;
}