Mercurial > hg > mlmmj
view src/mlmmj-send.c @ 7:e447e6033387
cleaned up bounce_from_adr()
author | mortenp |
---|---|
date | Thu, 22 Apr 2004 20:08:01 +1000 |
parents | 762570b02394 |
children | 6068d81dd54a |
line wrap: on
line source
/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk> * * $Id$ * * This file is redistributable under version 2 of the GNU General * Public License as described at http://www.gnu.org/licenses/gpl.txt */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <strings.h> #include <sys/stat.h> #include <fcntl.h> #include "mlmmj-send.h" #include "mlmmj.h" #include "mail-functions.h" #include "itoa.h" #include "incindexfile.h" #include "chomp.h" #include "checkwait_smtpreply.h" #include "getlistaddr.h" #include "init_sockfd.h" #include "strgen.h" #include "log_error.c" static void print_help(const char *prg) { printf("Usage: %s -L /path/to/chat-list -m /path/to/mail\n", prg); exit(EXIT_SUCCESS); } static char *bounce_from_adr(char *recipient, char *listadr, char *mailfilename) { char *bounce_adr; char *indexstr, *listdomain, *a; size_t len; indexstr = strrchr(mailfilename, '/'); if (!indexstr) indexstr = mailfilename; recipient = strdup(recipient); if (!recipient) { return NULL; } a = strchr(recipient, '@'); if (a) *a = '='; listadr = strdup(listadr); if (!listadr) { free(recipient); return NULL; } listdomain = strchr(listadr, '@'); if (!listdomain) { free(recipient); free(listadr); } *listdomain++ = '\0'; // 11 = "-bounces" + RECIPDELIM + "@" + NUL len = strlen(listadr) + strlen(recipient) + strlen(listdomain) + 11; bounce_adr = malloc(len); if (!bounce_adr) { free(recipient); free(listadr); return NULL; } snprintf(bounce_adr, len, "%s-bounces%c%s@%s", listadr, RECIPDELIM, recipient, listdomain); free(recipient); free(listadr); return bounce_adr; } int send_mail(int sockfd, const char *from, const char *to, const char *replyto, FILE *mailfile) { int retval; if((retval = write_mail_from(sockfd, from)) != 0) { log_error("Could not write MAIL FROM\n"); /* FIXME: Queue etc.*/ write_rset(sockfd); return retval; } if((retval = checkwait_smtpreply(sockfd, MLMMJ_FROM)) != 0) { log_error("Wrong MAIL FROM:\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((retval = write_rcpt_to(sockfd, to)) != 0) { log_error("Could not write RCPT TO:\n"); /* FIXME: Queue etc.*/ write_rset(sockfd); return retval; } if((retval = checkwait_smtpreply(sockfd, MLMMJ_RCPTTO)) != 0) { log_error("Wrong RCPT TO:\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((retval = write_data(sockfd)) != 0) { log_error("Could not write DATA\b"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((checkwait_smtpreply(sockfd, MLMMJ_DATA)) != 0) { log_error("Mailserver not ready for DATA\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if(replyto) if((retval = write_replyto(sockfd, replyto)) != 0) { log_error("Could not write reply-to addr.\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((retval = write_mailbody_from_file(sockfd, mailfile)) != 0) { log_error("Could not write mailbody\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((retval = write_dot(sockfd)) != 0) { log_error("Could not write <CR><LF>.<CR><LF>\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } if((checkwait_smtpreply(sockfd, MLMMJ_DOT)) != 0) { log_error("Mailserver did not acknowledge end of mail\n" "<CR><LF>.<CR><LF> was written, to no" "avail\n"); write_rset(sockfd); /* FIXME: Queue etc.*/ return retval; } return 0; } int main(int argc, char **argv) { size_t len = 0; int sockfd = 0, opt, mindex, retval=0; FILE *subfile = 0, *mailfile = 0; char *mailfilename = 0; char *subfilename = 0; char *listdir = 0; char listadr[READ_BUFSIZE]; char *replyto = 0; char *bounce_adr = 0; char *to_addr = 0; char *archivefilename = 0; char buf[READ_BUFSIZE]; char *bufres; char *relayhost = 0; int deletewhensent = 1; log_set_name(argv[0]); while ((opt = getopt(argc, argv, "VDhm:L:R:F:T:r:")) != -1){ switch(opt) { case 'D': deletewhensent = 0; break; case 'F': bounce_adr = optarg; break; case 'h': print_help(argv[0]); break; case 'L': listdir = optarg; break; case 'm': mailfilename = optarg; break; case 'r': relayhost = optarg; break; case 'R': replyto = optarg; break; case 'T': to_addr = optarg; break; case 'V': print_version(argv[0]); exit(0); } } if(mailfilename == 0 || listdir == 0) { fprintf(stderr, "You have to specify -L and -m\n"); fprintf(stderr, "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } /* get the list address */ if(listdir[0] == '1' && (bounce_adr == 0 || to_addr == 0)) fprintf(stderr, "With -L 1 you need -F and -T\n"); if(listdir[0] != '1') getlistaddr(listadr, listdir); /* initialize file with mail to send */ if((mailfile = fopen(mailfilename, "r")) == NULL) { log_error(mailfilename); exit(EXIT_FAILURE); } if(relayhost) init_sockfd(&sockfd, relayhost); else init_sockfd(&sockfd, RELAYHOST); /* XXX: Here is the subscribers unrolled and mails are sent. * A more intelligent generic solution will be implemented * later, so we can get LDAP, SQL etc. support for the * subscribers list. Choeger? */ if(listdir[0] != '1') { subfilename = concatstr(2, listdir, "/subscribers"); if((subfile = fopen(subfilename, "r")) == NULL) { log_error("Could not open subscriberfile:"); exit(EXIT_FAILURE); } } /* initialize the archive filename */ if(listdir[0] != '1') { mindex = incindexfile((const char *)listdir, 1); len = strlen(listdir) + 9 + 20; archivefilename = malloc(len); snprintf(archivefilename, len, "%s/archive/%d", listdir, mindex); } if((retval = checkwait_smtpreply(sockfd, MLMMJ_CONNECT)) != 0) { log_error("No proper greeting to our connect\n" "We continue and hope for the best\n"); /* FIXME: Queue etc. */ } write_helo(sockfd, "localhost"); if((checkwait_smtpreply(sockfd, MLMMJ_HELO)) != 0) { log_error("Error with HELO\n" "We continue and hope for the best\n"); /* FIXME: quit and tell admin to configure correctly */ } if(listdir[0] != '1') { while((bufres = fgets(buf, READ_BUFSIZE, subfile))) { chomp(buf); bounce_adr = bounce_from_adr(buf, listadr, archivefilename); send_mail(sockfd, bounce_adr, buf, 0, mailfile); free(bounce_adr); } } else send_mail(sockfd, bounce_adr, to_addr, replyto, mailfile); write_quit(sockfd); if((checkwait_smtpreply(sockfd, MLMMJ_QUIT)) != 0) { log_error("Mailserver would not let us QUIT\n" "We close the socket anyway though\n"); } if(listdir[0] != '1') { /* The mail now goes to the archive */ rename(mailfilename, archivefilename); fclose(subfile); free(archivefilename); free(subfilename); } else if(deletewhensent) unlink(mailfilename); close(sockfd); fclose(mailfile); return EXIT_SUCCESS; }