Mercurial > hg > mlmmj
changeset 174:8a565328fa73
Instead of reading 1 line at a time in mlmmj-send everytime we send the
mail, mmap it once, and pass the pointer to the send function which
writes one line at a time with proper \n -> \r\n and '.' -> '..'
conversion.
author | mmj |
---|---|
date | Sat, 05 Jun 2004 23:49:11 +1000 |
parents | c91c37f083a6 |
children | b26303f1b442 |
files | src/mail-functions.c src/mlmmj-send.c |
diffstat | 2 files changed, 58 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/src/mail-functions.c Sat Jun 05 23:48:07 2004 +1000 +++ b/src/mail-functions.c Sat Jun 05 23:49:11 2004 +1000 @@ -6,8 +6,6 @@ * Public License as described at http://www.gnu.org/licenses/gpl.txt */ -#include "mail-functions.h" -#include "wrappers.h" #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -17,9 +15,10 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> -#include <sys/stat.h> #include <fcntl.h> +#include "mail-functions.h" +#include "wrappers.h" #include "log_error.h" /* "HELO \r\n " has length 7 */ @@ -101,63 +100,31 @@ } -int write_mailbody_from_fd(int sockfd, int fd) +int write_mailbody_from_map(int sockfd, char *mapstart, size_t size) { - char buf[WRITE_BUFSIZE+3]; - size_t len, bytes_written; - char *bufp; - int full_line = 1; /* true, if last write included a newline */ - - /* Zero the buffer */ - memset(buf, 0, sizeof(buf)); - - /* Read from beginning of the file */ - - if(lseek(fd, 0L, SEEK_SET) < 0) { - log_error(LOG_ARGS, "lseek() failed"); - return errno; - } - - /* keep writing chunks of line (max WRITE_BUFSIZE) */ - for(;;) { - bufp = buf+1; - - len = read(fd, bufp, WRITE_BUFSIZE); - - if(len == 0) - return 0; + char *cur, *next; + char newlinebuf[3]; + size_t len; - if(len < 0) { - if (errno == EINTR) { - continue; - } else { - return errno; - } - } - - /* fix "dot lines" */ - if(full_line && (bufp[0] == '.')) { - *(--bufp) = '.'; - len++; + for(next = cur = mapstart; next < mapstart + size; next++) { + if(*next == '\n') { + if(writen(sockfd, cur, next - cur) < 0) { + log_error(LOG_ARGS, "Could not write mail"); + return -1; } - - /* fix newlines */ - if((len > 0) && (bufp[len-1] == '\n')) { - bufp[len-1] = '\r'; - bufp[len] = '\n'; - bufp[len+1] = 0; - len++; - full_line = 1; - } else { - full_line = 0; + newlinebuf[0] = '\r'; + newlinebuf[1] = '\n'; + len = 2; + if(*(next+1) == '.') { + newlinebuf[2] = '.'; + len = 3; } - -#if 0 - fprintf(stderr, "write_mailbody_from_file = [%s]\n", bufp); -#endif - bytes_written = writen(sockfd, bufp, len); - if(bytes_written < 0 ) - return errno; + if(writen(sockfd, newlinebuf, len) < 0) { + log_error(LOG_ARGS, "Could not write mail"); + return -1; + } + cur = next + 1; + } } return 0;
--- a/src/mlmmj-send.c Sat Jun 05 23:48:07 2004 +1000 +++ b/src/mlmmj-send.c Sat Jun 05 23:49:11 2004 +1000 @@ -11,7 +11,6 @@ #include <unistd.h> #include <errno.h> #include <string.h> -#include <strings.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> @@ -21,6 +20,7 @@ #include <libgen.h> #include <syslog.h> #include <stdarg.h> +#include <sys/mman.h> #include "mlmmj-send.h" #include "mlmmj.h" @@ -141,7 +141,7 @@ } int send_mail(int sockfd, const char *from, const char *to, - const char *replyto, int mailfd, + const char *replyto, char *mailmap, size_t mailsize, const char *listdir, const char *mlmmjbounce) { int retval = 0; @@ -206,7 +206,7 @@ } } - retval = write_mailbody_from_fd(sockfd, mailfd); + retval = write_mailbody_from_map(sockfd, mailmap, mailsize); if(retval) { log_error(LOG_ARGS, "Could not write mailbody\n"); return retval; @@ -279,9 +279,9 @@ } int send_mail_many(int sockfd, const char *from, const char *replyto, - int mailfd, int subfd, const char *listaddr, - const char *archivefilename, const char *listdir, - const char *mlmmjbounce) + char *mailmap, size_t mailsize, int subfd, + const char *listaddr, const char *archivefilename, + const char *listdir, const char *mlmmjbounce) { int sendres = 0, addrfd; char *bounceaddr, *addr, *index, *dirname, *addrfilename; @@ -291,12 +291,12 @@ chomp(addr); if(from) sendres = send_mail(sockfd, from, addr, replyto, - mailfd, listdir, NULL); + mailmap, mailsize, listdir, NULL); else { bounceaddr = bounce_from_adr(addr, listaddr, archivefilename); sendres = send_mail(sockfd, bounceaddr, addr, replyto, - mailfd, listdir, mlmmjbounce); + mailmap, mailsize, listdir, mlmmjbounce); free(bounceaddr); } if(sendres && listaddr && archivefilename) { @@ -378,9 +378,10 @@ char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL; char *relayhost = NULL, *archivefilename = NULL, *tmpstr; char *listctrl = NULL, *subddirname = NULL, *listdir = NULL; - char *mlmmjbounce = NULL, *bindir; + char *mlmmjbounce = NULL, *bindir, *mailmap; DIR *subddir; struct dirent *dp; + struct stat st; log_set_name(argv[0]); @@ -463,6 +464,17 @@ exit(EXIT_FAILURE); } + if(fstat(mailfd, &st) < 0) { + log_error(LOG_ARGS, "Could not stat mailfd"); + exit(EXIT_FAILURE); + } + + mailmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED, mailfd, 0); + if(mailmap == (void *)-1) { + log_error(LOG_ARGS, "Could not mmap mailfd"); + exit(EXIT_FAILURE); + } + switch(listctrl[0]) { case '1': /* A single mail is to be sent, do nothing */ break; @@ -504,8 +516,8 @@ switch(listctrl[0]) { case '1': /* A single mail is to be sent */ initsmtp(&sockfd, relayhost); - sendres = send_mail(sockfd, bounceaddr, to_addr, - replyto, mailfd, listdir, NULL); + sendres = send_mail(sockfd, bounceaddr, to_addr, replyto, + mailmap, st.st_size, listdir, NULL); endsmtp(&sockfd); if(sendres) { /* error, so keep it in the queue */ @@ -546,16 +558,17 @@ break; case '2': /* Moderators */ initsmtp(&sockfd, relayhost); - if(send_mail_many(sockfd, bounceaddr, NULL, mailfd, subfd, - NULL, NULL, listdir, NULL)) + if(send_mail_many(sockfd, bounceaddr, NULL, mailmap, st.st_size, + subfd, NULL, NULL, listdir, NULL)) close(sockfd); else endsmtp(&sockfd); break; case '3': /* resending earlier failed mails */ initsmtp(&sockfd, relayhost); - if(send_mail_many(sockfd, NULL, NULL, mailfd, subfd, - listaddr, mailfilename, listdir, mlmmjbounce)) + if(send_mail_many(sockfd, NULL, NULL, mailmap, st.st_size, + subfd, listaddr, mailfilename, listdir, + mlmmjbounce)) close(sockfd); else endsmtp(&sockfd); @@ -588,9 +601,9 @@ free(subfilename); initsmtp(&sockfd, relayhost); - sendres = send_mail_many(sockfd, NULL, NULL, mailfd, - subfd, listaddr, archivefilename, - listdir, mlmmjbounce); + sendres = send_mail_many(sockfd, NULL, NULL, mailmap, + st.st_size, subfd, listaddr, + archivefilename, listdir, mlmmjbounce); if (sendres) { /* If send_mail_many() failed we close the * connection to the mail server in a brutal @@ -606,12 +619,14 @@ break; } + munmap(mailmap, st.st_size); + close(mailfd); + if(archive) { rename(mailfilename, archivefilename); free(archivefilename); } else if(deletewhensent) unlink(mailfilename); - close(mailfd); return EXIT_SUCCESS; }