/* * 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; }