From: Baptiste Daroussin Date: Fri, 14 Apr 2023 15:26:08 +0000 (+0200) Subject: gethdrline: rewrite to use stdio X-Git-Tag: RELEASE_1_4_0b1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11451bb2c9ca5626e3555bf022b1f80d33ff6056;p=thirdparty%2Fmlmmj.git gethdrline: rewrite to use stdio It simplifies a bit the code and allows a more complete code coverage --- diff --git a/include/gethdrline.h b/include/gethdrline.h index 434ed5e1..5521d11e 100644 --- a/include/gethdrline.h +++ b/include/gethdrline.h @@ -1,6 +1,6 @@ -/* Copyright (C) 2004 Mads Martin Joergensen - * - * $Id$ +/* + * Copyright (C) 2004 Mads Martin Joergensen + * Copyright (C) 2023 Baptiste Daroussin * * 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); diff --git a/src/do_all_the_voodoo_here.c b/src/do_all_the_voodoo_here.c index c1c69fd0..7b50d15e 100644 --- a/src/do_all_the_voodoo_here.c +++ b/src/do_all_the_voodoo_here.c @@ -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) diff --git a/src/gethdrline.c b/src/gethdrline.c index b3c95f2d..5690708e 100644 --- a/src/gethdrline.c +++ b/src/gethdrline.c @@ -34,65 +34,46 @@ #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); } diff --git a/src/mlmmj-bounce.c b/src/mlmmj-bounce.c index bcc17376..c5b0a2be 100644 --- a/src/mlmmj-bounce.c +++ b/src/mlmmj-bounce.c @@ -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" diff --git a/src/mlmmj.c b/src/mlmmj.c index 88f86ca1..c9834d06 100644 --- a/src/mlmmj.c +++ b/src/mlmmj.c @@ -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; } diff --git a/src/send_digest.c b/src/send_digest.c index 3909d18a..fe13aff3 100644 --- a/src/send_digest.c +++ b/src/send_digest.c @@ -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; diff --git a/tests/mlmmj.c b/tests/mlmmj.c index f1140657..808a6ad3 100644 --- a/tests/mlmmj.c +++ b/tests/mlmmj.c @@ -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)