]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Instead of reading 1 line at a time in mlmmj-send everytime we send the
authormmj <none@none>
Sat, 5 Jun 2004 13:49:11 +0000 (23:49 +1000)
committermmj <none@none>
Sat, 5 Jun 2004 13:49:11 +0000 (23:49 +1000)
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.

src/mail-functions.c
src/mlmmj-send.c

index e321e9faed19d9520ab1a3ff0045454b02815fb2..d69b2ddbd89d3b0d5b1aa4041c6ebbfdae9bca42 100644 (file)
@@ -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>
 #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_rcpt_to(int sockfd, const char *rcpt_addr)
 }
 
 
-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;
-                       
-               if(len < 0) {
-                       if (errno == EINTR) {
-                               continue;
-                       } else {
-                               return errno;
+       char *cur, *next;
+       char newlinebuf[3];
+       size_t 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;
                        }
+                       newlinebuf[0] = '\r';
+                       newlinebuf[1] = '\n';
+                       len = 2;
+                       if(*(next+1) == '.') {
+                               newlinebuf[2] = '.';
+                               len = 3;
+                       }
+                       if(writen(sockfd, newlinebuf, len) < 0) {
+                               log_error(LOG_ARGS, "Could not write mail");
+                               return -1;
+                       }
+                       cur = next + 1;
                }
-
-               /* fix "dot lines" */
-               if(full_line && (bufp[0] == '.')) {
-                       *(--bufp) = '.';
-                       len++;
-               }
-
-               /* 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;
-               }
-
-#if 0
-               fprintf(stderr, "write_mailbody_from_file = [%s]\n", bufp);
-#endif
-               bytes_written = writen(sockfd, bufp, len);
-               if(bytes_written < 0 )
-                       return errno;
        }
 
        return 0;
index c97651802a5b334b7da6f722ada3919106850641..b2c4c4d7cd5c76039c260e8c2f2693477b81279a 100644 (file)
@@ -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,12 +141,12 @@ int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from)
 }
 
 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;
        char *reply;
-
+       
        retval = write_mail_from(sockfd, from);
        if(retval) {
                log_error(LOG_ARGS, "Could not write MAIL FROM\n");
@@ -206,7 +206,7 @@ int send_mail(int sockfd, const char *from, const char *to,
                }
        }
 
-       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 endsmtp(int *sockfd)
 }
 
 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 @@ int send_mail_many(int sockfd, const char *from, const char *replyto,
                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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
        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 @@ int main(int argc, char **argv)
                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 @@ int main(int argc, char **argv)
                        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 @@ int main(int argc, char **argv)
                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;
 }