]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
gethdrline: rewrite to use stdio
authorBaptiste Daroussin <bapt@FreeBSD.org>
Fri, 14 Apr 2023 15:26:08 +0000 (17:26 +0200)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Fri, 14 Apr 2023 15:26:08 +0000 (17:26 +0200)
It simplifies a bit the code and allows a more complete code coverage

include/gethdrline.h
src/do_all_the_voodoo_here.c
src/gethdrline.c
src/mlmmj-bounce.c
src/mlmmj.c
src/send_digest.c
tests/mlmmj.c

index 434ed5e1e2b19eeb6ef81572dd95aef946cda2be..5521d11e5c589bf5647dd72884e059d246c6620c 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
- *
- * $Id$
+/*
+ * Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2023 Baptiste Daroussin <bapt@FreeBSD.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -21,9 +21,6 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef GETHDRLINE_H
-#define GETHDRLINE_H
-
-char *gethdrline(int fd,char **unfolded);
+#pragma once
 
-#endif /* GETHDRLINE_H */
+char *gethdrline(FILE *f,char **unfolded);
index c1c69fd0a62eb4c645f65cc7bd267186dede0ecb..7b50d15efe1d9866425f65a7645fb5d0d057255e 100644 (file)
@@ -78,9 +78,11 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
        char *hdrline, *unfolded, *unqp;
        bool hdrsadded = false;
        bool subject_present = false;
+       int localfd = dup(infd);
+       FILE *f = fdopen(localfd, "r");
 
        for(;;) {
-               hdrline = gethdrline(infd, &unfolded);
+               hdrline = gethdrline(f, &unfolded);
 
                /* add extra headers before MIME* headers,
                   or after all headers */
@@ -150,11 +152,13 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                free(unfolded);
        }
 
+       lseek(localfd, ftello(f), SEEK_SET);
        /* Just print the rest of the mail */
-       if(dumpfd2fd(infd, outfd) < 0) {
+       if(dumpfd2fd(localfd, outfd) < 0) {
                log_error(LOG_ARGS, "Error when dumping rest of mail");
                return -1;
        }
+       fclose(f);
 
        /* No more, let's add the footer if one */
        if(footfd >= 0)
index b3c95f2d15a1747abe5016244378445cadc266ad..5690708ecfbe9312049458b54cef0905ef61cc8b 100644 (file)
 #include "chomp.h"
 
 
-char *gethdrline(int fd, char **unfolded)
+char *gethdrline(FILE *f, char **unfolded)
 {
        char *line = NULL, *retstr = NULL, *oldretstr = NULL, *oldunfolded = NULL;
        char ch;
-       ssize_t n;
+       size_t linecap = 0;
 
-       retstr = mygetline(fd);
-       if (!retstr) {
+       if (getline(&line, &linecap, f) <= 0) {
                if (unfolded != NULL)
                        *unfolded = NULL;
                return NULL;
        }
 
        if (unfolded != NULL)
-               *unfolded = xstrdup(retstr);
+               *unfolded = xstrdup(line);
 
-       chomp(retstr);
+       chomp(line);
 
        /* end-of-headers */
-       if (*retstr == '\0') {
+       if (*line == '\0') {
                if (unfolded != NULL) {
                        free(*unfolded);
                        *unfolded = NULL;
                }
-               free(retstr);
+               free(line);
                return NULL;
        }
 
+       retstr = xstrdup(line);
        for(;;) {
                /* look ahead one char to determine if we need to fold */
-               n = readn(fd, &ch, 1);
-               if (n == 0) {  /* end of file, and therefore also headers */
-                       return retstr;
-               } else if (n == -1) {  /* error */
-                       log_error(LOG_ARGS, "readn() failed in gethdrline()");
-                       if (unfolded != NULL) {
-                               free(*unfolded);
-                               *unfolded = NULL;
-                       }
-                       free(retstr);
-                       return NULL;
-               }
-
-               if (lseek(fd, -1, SEEK_CUR) == (off_t)-1) {
-                       log_error(LOG_ARGS, "lseek() failed in gethdrline()");
-                       if (unfolded != NULL) {
-                               free(*unfolded);
-                               *unfolded = NULL;
-                       }
-                       free(retstr);
-                       return NULL;
-               }
+               ch = fgetc(f);
+               if (ch == EOF)
+                       goto out;
 
+               ungetc(ch, f);
                if ((ch != '\t') && (ch != ' '))  /* no more folding */
-                       return retstr;
+                       goto out;
 
-               line = mygetline(fd);
-               if (!line)
-                       return retstr;
+               if (getline(&line, &linecap, f) <= 0)
+                       goto out;
 
                if (unfolded != NULL) {
                        oldunfolded = *unfolded;
@@ -106,7 +87,8 @@ char *gethdrline(int fd, char **unfolded)
                xasprintf(&retstr, "%s%s",
                    oldretstr != NULL ? oldretstr : "", line);
                free(oldretstr);
-
-               free(line);
        }
+out:
+       free(line);
+       return (retstr);
 }
index bcc17376925123b8b62aef5bd8b7a4b1d145da6d..c5b0a2bef4cc67a4590aa194879a2d26d53eaced 100644 (file)
@@ -46,7 +46,6 @@
 #include "prepstdreply.h"
 #include "xmalloc.h"
 #include "find_email_adr.h"
-#include "gethdrline.h"
 #include "utils.h"
 #include "send_mail.h"
 
index 88f86ca129e22ca7aecc4b12ae1d77aed0d523c7..c9834d06f6c4d1fb796f990233085763779e99a9 100644 (file)
@@ -405,20 +405,22 @@ save_lastbouncedmsg(int listfd, const char *address, const char *mailname)
 
 char *dsnparseaddr(const char *mailname)
 {
-       int fd;
+       FILE *f;
+       char *buf = NULL;
+       size_t bufcap = 0;
        char *line, *hdr, *walk, *addr = NULL, *boundary = NULL;
        bool quoted = false;
        bool indsn = false;
        strlist emails = tll_init();
 
-       fd = open(mailname, O_RDONLY);
-       if(fd < 0) {
+       f = fopen(mailname, "r");
+       if(f == NULL) {
                log_error(LOG_ARGS, "Could not open bounceindexfile %s",
                                mailname);
                return NULL;
        }
 
-       while((line = gethdrline(fd, NULL))) {
+       while((line = gethdrline(f, NULL))) {
                if (strncasecmp(line, "content-type:", 13) != 0) {
                        free(line);
                        continue;
@@ -458,13 +460,12 @@ char *dsnparseaddr(const char *mailname)
        /* this is not a miltipart/report mail see RFC1839 */
        if (boundary == NULL)
                return NULL;
-       while ((line = mygetline(fd))) {
-               chomp(line);
+       while ((getline(&buf, &bufcap, f) > 0)) {
+               chomp(buf);
                if (indsn) {
-                       if (strncasecmp(line, "Final-Recipient:", 16) == 0) {
-                               walk = strchr(line, ';');
+                       if (strncasecmp(buf, "Final-Recipient:", 16) == 0) {
+                               walk = strchr(buf, ';');
                                if (walk == NULL) {
-                                       free(line);
                                        break;
                                }
                                find_email_adr(walk+1, &emails);
@@ -472,17 +473,16 @@ char *dsnparseaddr(const char *mailname)
                                        addr = xstrdup(tll_front(emails));
                                        tll_free_and_free(emails, free);
                                }
-                               free(line);
                                break;
                        }
                }
-               if (strcmp(line, boundary) == 0) {
+               if (strcmp(buf, boundary) == 0) {
                        if (indsn) {
-                               free(line);
+                               free(buf);
                                break;
                        }
                        /* check our content type is a valid one */
-                       while ((hdr = gethdrline(fd, NULL))) {
+                       while ((hdr = gethdrline(f, NULL))) {
                                if (indsn) {
                                        /* skip the rest of the headers if any */
                                        free(hdr);
@@ -503,8 +503,8 @@ char *dsnparseaddr(const char *mailname)
                                indsn = true;
                        }
                }
-               free(line);
        }
+       free(line);
        return addr;
 }
 
index 3909d18ae0c7d787b099ad17c0e0fa157dff586c..fe13aff352904c373dde60178c9459e4f00b18f1 100644 (file)
@@ -86,8 +86,10 @@ static thread_list_state *init_thread_list(
 static void rewind_thread_list(void * state)
 {
        thread_list_state *s = (thread_list_state *)state;
+       FILE *archivef;
        int i, j, archivefd, thread_idx;
-       char *line, *tmp, *subj, *from, *tmpfrom;
+       char *line = NULL, *tmp, *subj, *from, *tmpfrom;
+       size_t linecap = 0;
        char *archivename;
        int num_threads = 0;
        struct thread *threads = NULL;
@@ -102,16 +104,16 @@ static void rewind_thread_list(void * state)
 
        for (i=s->firstindex; i<=s->lastindex; i++) {
                xasprintf(&archivename, "%s/archive/%d", s->listdir, i);
-               archivefd = open(archivename, O_RDONLY);
+               archivef = fopen(archivename, "r");
                free(archivename);
 
-               if (archivefd < 0)
+               if (archivef == NULL)
                        continue;
 
                subj = NULL;
                from = NULL;
 
-               while ((line = gethdrline(archivefd, NULL))) {
+               while (getline(&line, &linecap, archivef) > 0) {
                        if (strncasecmp(line, "Subject:", 8) == 0) {
                                free(subj);
                                subj = unistr_header_to_utf8(line + 8);
@@ -120,7 +122,6 @@ static void rewind_thread_list(void * state)
                                free(from);
                                from = unistr_header_to_utf8(line + 5);
                        }
-                       free(line);
                }
 
                if (!subj) {
@@ -182,8 +183,9 @@ static void rewind_thread_list(void * state)
                free(subj);
                free(from);
 
-               close(archivefd);
+               fclose(archivef);
        }
+       free(line);
 
        s->num_threads = num_threads;
        s->threads = threads;
index f1140657ecd3bdfdbf012a17f67439fc7a5a0fa5..808a6ad370ec74fa6f545e9b55a960311779f48c 100644 (file)
@@ -2559,40 +2559,40 @@ ATF_TC_BODY(gethdrline, tc)
        atf_utils_create_file("mail3", "From: bob");
        atf_utils_create_file("mail4", "From: bob\nTo: Jane\nSubject: bla\r\n\nplop.\n");
        atf_utils_create_file("mail5", "From: bob\n  grmbl\nTo: Jane\n\t");
-       int fd;
+       FILE *f;
        char *plop, *l;
-       fd = open("mail1", O_RDONLY);
-       ATF_REQUIRE(gethdrline(fd, NULL) == NULL);
-       ATF_REQUIRE(gethdrline(fd, &plop) == NULL);
+       f = fopen("mail1", "r");
+       ATF_REQUIRE(gethdrline(f, NULL) == NULL);
+       ATF_REQUIRE(gethdrline(f, &plop) == NULL);
        ATF_REQUIRE(plop == NULL);
-       close(fd);
-       fd = open("mail2", O_RDONLY);
-       ATF_REQUIRE(gethdrline(fd, NULL) == NULL);
-       close(fd);
-       fd = open("mail3", O_RDONLY);
-       l = gethdrline(fd, NULL);
+       fclose(f);
+       f = fopen("mail2", "r");
+       ATF_REQUIRE(gethdrline(f, NULL) == NULL);
+       fclose(f);
+       f = fopen("mail3", "r");
+       l = gethdrline(f, NULL);
        ATF_REQUIRE_STREQ(l, "From: bob");
-       close(fd);
-       fd = open("mail4", O_RDONLY);
-       l = gethdrline(fd, NULL);
+       fclose(f);
+       f = fopen("mail4", "r");
+       l = gethdrline(f, NULL);
        ATF_REQUIRE_STREQ(l, "From: bob");
-       l = gethdrline(fd, &plop);
+       l = gethdrline(f, &plop);
        ATF_REQUIRE_STREQ(l, "To: Jane");
        ATF_REQUIRE_STREQ(plop, "To: Jane\n");
-       l = gethdrline(fd, &plop);
+       l = gethdrline(f, &plop);
        ATF_REQUIRE_STREQ(l, "Subject: bla");
        ATF_REQUIRE_STREQ(plop, "Subject: bla\r\n");
-       l = gethdrline(fd, &plop);
+       l = gethdrline(f, &plop);
        ATF_REQUIRE(l == NULL);
-       close(fd);
-       fd = open("mail5", O_RDONLY);
-       l = gethdrline(fd, &plop);
+       fclose(f);
+       f = fopen("mail5", "r");
+       l = gethdrline(f, &plop);
        ATF_REQUIRE_STREQ(l, "From: bob  grmbl");
        ATF_REQUIRE_STREQ(plop, "From: bob\n  grmbl\n");
-       l = gethdrline(fd, &plop);
+       l = gethdrline(f, &plop);
        ATF_REQUIRE_STREQ(l, "To: Jane\t");
        ATF_REQUIRE_STREQ(plop, "To: Jane\n\t");
-       close(fd);
+       fclose(f);
 }
 
 ATF_TP_ADD_TCS(tp)