From 97117caecb88757b1efa045b5fa657b5ced82265 Mon Sep 17 00:00:00 2001 From: Christian Csar <902242+cacsar@users.noreply.github.com> Date: Sat, 22 Feb 2020 20:33:05 -0800 Subject: [PATCH 01/25] Fix quotation for `make install` --- Makefile.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.in b/Makefile.in index caeb383a..c679d37d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,14 +47,14 @@ support: @cd archive; $(MAKE) all CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" install: - @cd src; $(MAKE) install CC="$(CC)" CFLAGS="$(CFLAGS) \ - "CPPFLAGS="$(CPPFLAGS)" \ + @cd src; $(MAKE) install CC="$(CC)" CFLAGS="$(CFLAGS)" \ + CPPFLAGS="$(CPPFLAGS)" \ cgidir="$(cgidir)" bindir="$(bindir)" LIBS="$(LIBS)" @cd docs; $(MAKE) install CC="$(CC)" CFLAGS="$(CFLAGS)" \ - "CPPFLAGS="$(CPPFLAGS)" \ + CPPFLAGS="$(CPPFLAGS)" \ $(MAKEFLAGS) mandir="$(mandir)" htmldir="$(htmldir)" @cd archive; $(MAKE) install CC="$(CC)" CFLAGS="$(CFLAGS)" \ - "CPPFLAGS="$(CPPFLAGS)" \ + CPPFLAGS="$(CPPFLAGS)" \ bindir="$(bindir)" uninstall: From fbaf12a634005a886347318af777a2cf5e3d3229 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 12 Jun 2020 10:11:57 +0200 Subject: [PATCH 02/25] Closes #63 --- Changelog | 11 +++++++++++ src/string.c | 44 +++++++++++++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/Changelog b/Changelog index ebe5e735..f0c83c73 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,16 @@ Version Changes for Hypermail ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +============================ +HYPERMAIL VERSION 2.4.1: +============================ + +2020-06-12 Jose Kahan + * src/parse.c + URLs were not detected and converted when they were preceeded by a : + that was not attached to a valid URL like foo: https://example.com or : + https://example.com. + ============================ HYPERMAIL VERSION 2.4.0: ============================ diff --git a/src/string.c b/src/string.c index 6d7003b4..4281c8a7 100644 --- a/src/string.c +++ b/src/string.c @@ -1802,22 +1802,40 @@ char *parseurl(char *input, char *charset) if (!input || !*input) return NULL; - c = strstr(input, ":"); + /* + * All our protocol prefixes have this ":" substring in them. Most + * of the lines we process don't have any URL. Let's not spend any + * time looking for URLs in lines that we can prove cheaply don't + * have any; it will be a big win for average input if we follow + * this trivial heuristic. + */ - if (!c /* not found */ - || c == input /* first char in line */ - || *(c+1) == '\0' /* last char in line */ - || !isalpha(*(c-1)) /* not between alpha/graph */ - || !isgraph(*(c+1))) { - /* - * All our protocol prefixes have this ":" substring in them. Most - * of the lines we process don't have any URL. Let's not spend any - * time looking for URLs in lines that we can prove cheaply don't - * have any; it will be a big win for average input if we follow - * this trivial heuristic. - */ + first = FALSE; + + c = strstr(input, ":"); + if (c == input) { /* first char in line */ + c++; + c = strstr(c, ":"); + } + + /* !c === not found */ + while (c) { + if (*(c+1) == '\0') /* last char in line */ + break; + else if ( !isalpha(*(c-1)) /* not between alpha/graph */ + || !isgraph(*(c+1))) { + c++; + c = strstr(c, ":"); + } else { + first = TRUE; + break; + } + } + + if (!first) { return convchars(input, charset); } + INIT_PUSH(buff); /* From 41565e66cc03563a85fe20d8f550aa565dbfe60f Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 12 Jun 2020 10:41:59 +0200 Subject: [PATCH 03/25] Closes #61 --- Changelog | 3 +++ configure | 41 +++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 ++ 3 files changed, 46 insertions(+) diff --git a/Changelog b/Changelog index f0c83c73..757e30d6 100644 --- a/Changelog +++ b/Changelog @@ -6,6 +6,9 @@ HYPERMAIL VERSION 2.4.1: ============================ 2020-06-12 Jose Kahan + * configure.ac + configure didn't signal an error if yacc was not installed + * src/parse.c URLs were not detected and converted when they were preceeded by a : that was not attached to a valid URL like foo: https://example.com or : diff --git a/configure b/configure index a9feaaad..7858d04e 100755 --- a/configure +++ b/configure @@ -709,6 +709,7 @@ LN_S INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +YACC_CHECK YFLAGS YACC CPP @@ -3444,6 +3445,46 @@ fi done test -n "$YACC" || YACC="yacc" +# Extract the first word of "$YACC", so it can be a program name with args. +set dummy $YACC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_YACC_CHECK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$YACC_CHECK"; then + ac_cv_prog_YACC_CHECK="$YACC_CHECK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_YACC_CHECK="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +YACC_CHECK=$ac_cv_prog_YACC_CHECK +if test -n "$YACC_CHECK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC_CHECK" >&5 +$as_echo "$YACC_CHECK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test x"$YACC_CHECK" != x"yes"; then : + as_fn_error $? "Please install either bison or yacc and run configure again" "$LINENO" 5 +fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: diff --git a/configure.ac b/configure.ac index 2a3b7fa9..79714bfd 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,8 @@ dnl =========================================================================== AC_PROG_CC AC_PROG_CPP AC_PROG_YACC +AC_CHECK_PROG(YACC_CHECK,$YACC,yes) +AS_IF([test x"$YACC_CHECK" != x"yes"], [AC_MSG_ERROR([Please install either bison or yacc and run configure again])]) AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET From ef967c311fa558845d9d9f0576a132248778bb30 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 12 Jun 2020 10:50:45 +0200 Subject: [PATCH 04/25] Changelog was missing commit #59 --- Changelog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 757e30d6..73e9c717 100644 --- a/Changelog +++ b/Changelog @@ -12,7 +12,11 @@ HYPERMAIL VERSION 2.4.1: * src/parse.c URLs were not detected and converted when they were preceeded by a : that was not attached to a valid URL like foo: https://example.com or : - https://example.com. + https://example.com + +2020-02-23 @cacsar + * Makefile.in + make install wasn't working ============================ HYPERMAIL VERSION 2.4.0: From 81664d192486e17e07cc9107e025a8d6af0f7ae2 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 12 Jun 2020 11:52:17 +0200 Subject: [PATCH 05/25] typos in changelog --- Changelog | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Changelog b/Changelog index 73e9c717..eec07a81 100644 --- a/Changelog +++ b/Changelog @@ -9,10 +9,10 @@ HYPERMAIL VERSION 2.4.1: * configure.ac configure didn't signal an error if yacc was not installed - * src/parse.c - URLs were not detected and converted when they were preceeded by a : - that was not attached to a valid URL like foo: https://example.com or : - https://example.com + * src/string.c + parseurl(): URLs were not detected and converted when they were + preceeded by a : that was not attached to a valid URL like + foo: https://example.com or : https://example.com 2020-02-23 @cacsar * Makefile.in From efec98c7387d2fe3641e571035f787c764e48da4 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 19 Jun 2020 18:10:44 +0200 Subject: [PATCH 06/25] Closes #64 --- Changelog | 8 ++++++++ src/domains.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/Changelog b/Changelog index eec07a81..1efe4ea7 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,14 @@ Version Changes for Hypermail HYPERMAIL VERSION 2.4.1: ============================ +2020-06-19 Jose Kahan + * domains.c + valid_root_domains() was validating a domain name against the + historical DNS domains such as .org, .com. DNS has evolved and allows a + bigger variety of domains than those this function verified. That part + of the function has been invalidated and will be either eventually + removed or evolve to a user-configurable option. + 2020-06-12 Jose Kahan * configure.ac configure didn't signal an error if yacc was not installed diff --git a/src/domains.c b/src/domains.c index be4ed92d..324a1322 100644 --- a/src/domains.c +++ b/src/domains.c @@ -18,6 +18,13 @@ int valid_root_domain(char *eaddr) if (!*name_to_check) return (0); + /* DNS has evolved and we have now a variety of new domains, hard + to track and that are not covered by this function. While temporary + waiting to see if we evolve this function to be user configurable, + we're going to return 1 (valid) all the time. 19/06/2020 -JK */ + return (1); + + for (ccptr = domain_codes; ccptr->domain != NULL; ccptr++) { if (strcasecmp(name_to_check, ccptr->domain) == 0) return (1); From 2604af96c85713bb1abe15497af6fc17d4e05678 Mon Sep 17 00:00:00 2001 From: jose Date: Thu, 27 Aug 2020 10:01:52 +0200 Subject: [PATCH 07/25] A naive approach to supporting U+00A0 nonbreakable space in parseurl --- Changelog | 8 +++++++- src/string.c | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Changelog b/Changelog index 1efe4ea7..ae1f981c 100644 --- a/Changelog +++ b/Changelog @@ -5,8 +5,14 @@ Version Changes for Hypermail HYPERMAIL VERSION 2.4.1: ============================ +2020-08-27 Jose Kahan + * src/string.c + extended parseurl() in a naive approach for supporting U+00A0 + nonbreakable space inside sscanf. This function should eventually be + rewritten to use libpcre + 2020-06-19 Jose Kahan - * domains.c + * src/domains.c valid_root_domains() was validating a domain name against the historical DNS domains such as .org, .com. DNS has evolved and allows a bigger variety of domains than those this function verified. That part diff --git a/src/string.c b/src/string.c index 4281c8a7..72844e81 100644 --- a/src/string.c +++ b/src/string.c @@ -1941,10 +1941,19 @@ char *parseurl(char *input, char *charset) && ((istelprotocol && (*inputp == '+' || isdigit(*inputp))) || (!istelprotocol && !ispunct(*inputp)))) { - if (set_iso2022jp) - urlscan = sscanf(inputp, "%255[^] \033)<>\"\'\n[\t\\]", urlbuff); - else - urlscan = sscanf(inputp, "%255[^] )<>\"\'\n[\t\\]", urlbuff); + if (set_iso2022jp) { + if (charset && !strncasecmp(charset, "UTF-8", 5)) { + urlscan = sscanf(inputp, "%255[^] \u00a0\033)<>\"\'\n[\t\\]", urlbuff); + } else { + urlscan = sscanf(inputp, "%255[^] \033)<>\"\'\n[\t\\]", urlbuff); + } + } else { + if (charset && !strncasecmp(charset, "UTF-8", 5)) { + urlscan = sscanf(inputp, "%255[^] \u00a0)<>\"\'\n[\t\\]", urlbuff); + } else { + urlscan = sscanf(inputp, "%255[^] )<>\"\'\n[\t\\]", urlbuff); + } + } } if (urlscan == 1) { From 172430250f97aad124dd4b7434daa9aac245c4ef Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 19 May 2021 11:49:25 +0200 Subject: [PATCH 08/25] Fix heap-use-after-free (noticed by libasan) --- src/parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parse.c b/src/parse.c index 36da5dfb..c561a0f2 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2378,6 +2378,7 @@ int parsemail(char *mbox, /* file name */ #endif if (charset) { free(charset); + charset = NULL; } charsetsave[0] = '\0'; From 4646e760e1beeeefb4b703ee0d88c38948450bbe Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 19 May 2021 11:50:03 +0200 Subject: [PATCH 09/25] Fix potential buffer overflow (noticed by libasan) --- src/uudecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uudecode.c b/src/uudecode.c index 4b4310d2..f5a7c20b 100644 --- a/src/uudecode.c +++ b/src/uudecode.c @@ -75,7 +75,7 @@ int uudecode(FILE *input, /* get file data from (if needed) */ if (init) { /* search for header line */ /* AUDIT biege: BOF in buf! */ - sprintf(scanfstring, "begin %%o %%%us", sizeof(buf)); + sprintf(scanfstring, "begin %%o %%%us", sizeof(buf) -1); while (2 != sscanf(iptr, scanfstring, &mode, buf)) { if (!fgets(buf, MAXPATHLEN, input)) { return 2; From d35936e386e558f331ca37115cf494eb9ea006fe Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 19 May 2021 15:27:16 +0200 Subject: [PATCH 10/25] Prevent another buffer overflow, reported by libasan --- src/parse.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/parse.c b/src/parse.c index c561a0f2..679514c2 100644 --- a/src/parse.c +++ b/src/parse.c @@ -924,7 +924,7 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) char charset[129]; char encoding[33]; char dummy[129]; - char *ptr; + char *ptr, *endptr; char *old_output; #ifdef NOTUSED @@ -959,6 +959,7 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) if (!strcasecmp("q", encoding)) { /* quoted printable decoding */ + endptr = ptr + strlen(ptr); #ifdef HAVE_ICONV char *orig2,*output2,*output3; @@ -967,7 +968,7 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) memset(output2,0,strlen(string)+1); old_output=output; - for (; *ptr; ptr++) { + for (; ptr < endptr; ptr++) { switch (*ptr) { case '=': sscanf(ptr + 1, "%02X", &value); @@ -991,7 +992,7 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) memcpy(charsetsave,charset,charsetlen); charsetsave[charsetlen] = '\0'; #else - for (; *ptr; ptr++) { + for (; ptr < endptr; ptr++) { switch (*ptr) { case '=': sscanf(ptr + 1, "%02X", &value); From 466b358fd131ccdc299f386955520ec70eece53f Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 4 Jun 2021 13:26:14 +0200 Subject: [PATCH 11/25] Reveerting 2604af9 --- Changelog | 6 ------ src/string.c | 17 ++++------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/Changelog b/Changelog index ae1f981c..3ec0c4c3 100644 --- a/Changelog +++ b/Changelog @@ -5,12 +5,6 @@ Version Changes for Hypermail HYPERMAIL VERSION 2.4.1: ============================ -2020-08-27 Jose Kahan - * src/string.c - extended parseurl() in a naive approach for supporting U+00A0 - nonbreakable space inside sscanf. This function should eventually be - rewritten to use libpcre - 2020-06-19 Jose Kahan * src/domains.c valid_root_domains() was validating a domain name against the diff --git a/src/string.c b/src/string.c index 72844e81..4281c8a7 100644 --- a/src/string.c +++ b/src/string.c @@ -1941,19 +1941,10 @@ char *parseurl(char *input, char *charset) && ((istelprotocol && (*inputp == '+' || isdigit(*inputp))) || (!istelprotocol && !ispunct(*inputp)))) { - if (set_iso2022jp) { - if (charset && !strncasecmp(charset, "UTF-8", 5)) { - urlscan = sscanf(inputp, "%255[^] \u00a0\033)<>\"\'\n[\t\\]", urlbuff); - } else { - urlscan = sscanf(inputp, "%255[^] \033)<>\"\'\n[\t\\]", urlbuff); - } - } else { - if (charset && !strncasecmp(charset, "UTF-8", 5)) { - urlscan = sscanf(inputp, "%255[^] \u00a0)<>\"\'\n[\t\\]", urlbuff); - } else { - urlscan = sscanf(inputp, "%255[^] )<>\"\'\n[\t\\]", urlbuff); - } - } + if (set_iso2022jp) + urlscan = sscanf(inputp, "%255[^] \033)<>\"\'\n[\t\\]", urlbuff); + else + urlscan = sscanf(inputp, "%255[^] )<>\"\'\n[\t\\]", urlbuff); } if (urlscan == 1) { From e5a2d278e8eb5a4eff3582d61af4fd3bfa4e3571 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 4 Jun 2021 18:30:21 +0200 Subject: [PATCH 12/25] small style fix --- src/uudecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uudecode.c b/src/uudecode.c index f5a7c20b..c0c978a0 100644 --- a/src/uudecode.c +++ b/src/uudecode.c @@ -75,7 +75,7 @@ int uudecode(FILE *input, /* get file data from (if needed) */ if (init) { /* search for header line */ /* AUDIT biege: BOF in buf! */ - sprintf(scanfstring, "begin %%o %%%us", sizeof(buf) -1); + sprintf(scanfstring, "begin %%o %%%us", sizeof(buf) - 1); while (2 != sscanf(iptr, scanfstring, &mode, buf)) { if (!fgets(buf, MAXPATHLEN, input)) { return 2; From 842dd8b6c64486ebb524ef0a7bf540a740d2ae60 Mon Sep 17 00:00:00 2001 From: jose Date: Fri, 4 Jun 2021 18:31:39 +0200 Subject: [PATCH 13/25] Update changelog entry with memory issues fixesd by Baptiste closes #68 --- Changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog b/Changelog index 3ec0c4c3..c3ab1ad3 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,10 @@ Version Changes for Hypermail HYPERMAIL VERSION 2.4.1: ============================ +2021-06-04 Baptiste Daroussin + * src/uudecode.c src/parse.c + Fixes for memory issues detected by libasan + 2020-06-19 Jose Kahan * src/domains.c valid_root_domains() was validating a domain name against the From 1fa5cc5ccfd016aaf341df6334d29c85e4cdaac7 Mon Sep 17 00:00:00 2001 From: David Hughes Date: Wed, 17 Nov 2021 17:48:47 +1100 Subject: [PATCH 14/25] Added support for strftime(3) formatting in the append_filename configuration so allow archived messages to be split over multiple mailboxes (monthly or yearly for example) --- docs/hmrc.html | 4 +--- src/Makefile.in | 2 +- src/parse.c | 35 ++++++++++++++++++++++++----------- src/setup.c | 4 +++- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/docs/hmrc.html b/docs/hmrc.html index 399be3ed..d2c97e74 100644 --- a/docs/hmrc.html +++ b/docs/hmrc.html @@ -1301,9 +1301,7 @@

System miscellaneous

append = 1
append_filename = [ string ]
-
Specifies the filename to be used by the append option. $DIR -may be used to specify a name relative to the directory specified -in the -d or dir option.
+
Specifies the filename to be used by the append option. $DIR may be used to specify a name relative to the directory specified in the -d or dir option. The string will be passed to strftime(3) to allow splitting the mailbox into yearly or monthy files, such as "%Y-%m.mbox".

append_filename = $DIR/INBOX
diff --git a/src/Makefile.in b/src/Makefile.in index 7f54bad0..2838fa4b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -40,7 +40,7 @@ CPPFLAGS=@CPPFLAGS@ @INCLUDES@ YACC=@YACC@ NETLIBS=@LIBS@ LDFLAGS=@LDFLAGS@ -MISC_LIBS= -lm -lpcre -ltrio +MISC_LIBS= -lpcre -ltrio -lm OPT_LIBS=@EXTRA_LIBS@ INCS= domains.h hypermail.h lang.h proto.h \ diff --git a/src/parse.c b/src/parse.c index 679514c2..6a446db7 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1531,6 +1531,7 @@ int parsemail(char *mbox, /* file name */ int num, isinheader, hassubject, hasdate; int num_added = 0; long exp_time = -1; + time_t curtime; time_t delete_older_than = (set_delete_older ? convtoyearsecs(set_delete_older) : 0); time_t delete_newer_than = (set_delete_newer ? convtoyearsecs(set_delete_newer) : 0); annotation_robot_t annotation_robot = ANNOTATION_ROBOT_NONE; @@ -1541,6 +1542,8 @@ int parsemail(char *mbox, /* file name */ int require_filter_len, require_filter_full_len; struct hmlist *tlist; char filename[MAXFILELEN]; + char directory[MAXFILELEN]; + char pathname[MAXFILELEN]; struct emailinfo *emp; char *att_dir = NULL; /* directory name to store attachments in */ char *meta_dir = NULL; /* directory name where we're storing the meta data @@ -1655,21 +1658,31 @@ int parsemail(char *mbox, /* file name */ if(set_append) { /* add to an mbox as we read */ - - if(set_append_filename && strncmp(set_append_filename, "$DIR/", 5)) { - if(strlen(set_append_filename) >= sizeof(filename)) - progerr("append_filename too long"); - strcpy(filename, set_append_filename); + *directory = 0; + *filename = 0; + *pathname = 0; + if (set_append_filename) { + time(&curtime); + if(strncmp(set_append_filename, "$DIR/", 5) == 0) { + strncpy(directory, dir, MAXFILELEN - 1); + strftime(filename, MAXFILELEN - 1, set_append_filename+5, + localtime(&curtime)); + } else { + strftime(filename, MAXFILELEN - 1, set_append_filename, + localtime(&curtime)); + } + } else { + strncpy(directory, dir, MAXFILELEN - 1); + strncpy(filename, "mbox", MAXFILELEN - 1); } - else if(trio_snprintf(filename, sizeof(filename), "%s%s", dir, - set_append_filename ? set_append_filename + 5 - : "mbox") - == sizeof(filename)) { + + if(trio_snprintf(pathname, sizeof(pathname), "%s%s", directory, + filename) == sizeof(pathname)) { progerr("Can't build mbox filename"); } - if(!(fpo = fopen(filename, "a"))) { + if(!(fpo = fopen(pathname, "a"))) { trio_snprintf(errmsg, sizeof(errmsg), "%s \"%s\".", - lang[MSG_CANNOT_OPEN_MAIL_ARCHIVE], filename); + lang[MSG_CANNOT_OPEN_MAIL_ARCHIVE], pathname); progerr(errmsg); } } diff --git a/src/setup.c b/src/setup.c index 3735391f..008d4b91 100644 --- a/src/setup.c +++ b/src/setup.c @@ -412,7 +412,9 @@ struct Config cfg[] = { {"append_filename", &set_append_filename, NULL, CFG_STRING, "# Specifies the filename to be used by the append option.\n" "# $DIR may be used to specify a name relative to the directory\n" - "# specified in the -d or dir option.\n", FALSE}, + "# specified in the -d or dir option.\n" + "# The string will be passed to strftime(3) to allow splitting the\n" + "# mailbox into yearly or monthy files, such as \"%Y-%m.mbox\".\n" , FALSE}, {"nonsequential", &set_nonsequential, BFALSE, CFG_SWITCH, "# Set this to On to generate filenames that are not sequential, but\n" From a5988481b53b290489403bb3dce721d87e17193f Mon Sep 17 00:00:00 2001 From: jose Date: Wed, 23 Mar 2022 23:01:41 +0100 Subject: [PATCH 15/25] replace non-ascii chars in header values for messages that don't respect RFC2047 --- src/parse.c | 3 +++ src/proto.h | 1 + src/string.c | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/parse.c b/src/parse.c index 679514c2..1ca2cb90 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1087,6 +1087,9 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) } else { free(storage); + /* make sure there are only ascii chars in the string + ** for messages that don't respect rfc2047 */ + i18n_replace_non_ascii_chars(string); return string; } } diff --git a/src/proto.h b/src/proto.h index 9fe9fc3e..affe20de 100644 --- a/src/proto.h +++ b/src/proto.h @@ -99,6 +99,7 @@ char *unobfuscate_email_address (char *); char *i18n_convstring(char *, char *, char *, size_t *); char *i18n_utf2numref(char *, int); unsigned char *i18n_numref2utf(char *); +int i18n_replace_non_ascii_chars(char *); char *PushByte(struct Push *, char); char *PushString(struct Push *, const char *); diff --git a/src/string.c b/src/string.c index 4281c8a7..f9e6b28b 100644 --- a/src/string.c +++ b/src/string.c @@ -452,6 +452,25 @@ unsigned char *i18n_numref2utf(char *string){ return headofutfstr; } +/* replaces all non 7-bit ascii chars in string by a ? +** returns the number of replaced chars +*/ +int i18n_replace_non_ascii_chars(char *string) +{ + char *ptr = string; + int count = 0; + + while (*ptr) { + if (!isascii(*ptr) || *ptr < 0x20) { + *ptr = '?'; + count++; + } + ptr++; + } + + return count; +} + #endif /* end of I18N hack */ From 68cac555d2a5b936fc10279e95d7e0f06814e551 Mon Sep 17 00:00:00 2001 From: jose Date: Thu, 24 Mar 2022 20:51:52 +0100 Subject: [PATCH 16/25] the non_ascii filter needs to ignore the 0x0d and 0x0a (\n\r) chars as they are not yet deleted when invoking this function --- src/string.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index f9e6b28b..91b8812b 100644 --- a/src/string.c +++ b/src/string.c @@ -461,7 +461,8 @@ int i18n_replace_non_ascii_chars(char *string) int count = 0; while (*ptr) { - if (!isascii(*ptr) || *ptr < 0x20) { + if (!isascii(*ptr) || + (*ptr < 0x20 && *ptr != 0x0a && *ptr != 0x0d)) { *ptr = '?'; count++; } From 717493298d5c26bbef02a996284911fe6ebfdf19 Mon Sep 17 00:00:00 2001 From: jose Date: Wed, 30 Mar 2022 18:42:36 +0200 Subject: [PATCH 17/25] code didn't set demimed flag to true --- src/parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parse.c b/src/parse.c index 1ca2cb90..64f6c375 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1813,6 +1813,7 @@ int parsemail(char *mbox, /* file name */ if (head->header && !head->demimed) { head->line = mdecodeRFC2047(head->line, strlen(head->line),charsetsave); + head->demimed = TRUE; } if (head->parsedheader || head->attached || From b02240f607bb97a80b594d3a57b3fac651b01daa Mon Sep 17 00:00:00 2001 From: jose Date: Wed, 30 Mar 2022 18:43:01 +0200 Subject: [PATCH 18/25] to take into account their unicode convertion, incrase by four the max size for storing the name of the sender of a message --- src/hypermail.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hypermail.h b/src/hypermail.h index 6a63c102..38d71ac9 100644 --- a/src/hypermail.h +++ b/src/hypermail.h @@ -135,7 +135,7 @@ #define NUMSTRLEN 10 #define MAXLINE 1024 #define MAXFILELEN 256 -#define NAMESTRLEN 80 +#define NAMESTRLEN 320 #define MAILSTRLEN 80 #define DATESTRLEN 80 #define MSGDSTRLEN 256 From 9244c356872f0010a69e3dcaa5df7e17bd4cd3b3 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Wed, 30 Mar 2022 18:43:01 +0200 Subject: [PATCH 19/25] to take into account their unicode convertion, incrase by four the max size for storing the name of the sender of a message --- src/hypermail.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hypermail.h b/src/hypermail.h index 6a63c102..38d71ac9 100644 --- a/src/hypermail.h +++ b/src/hypermail.h @@ -135,7 +135,7 @@ #define NUMSTRLEN 10 #define MAXLINE 1024 #define MAXFILELEN 256 -#define NAMESTRLEN 80 +#define NAMESTRLEN 320 #define MAILSTRLEN 80 #define DATESTRLEN 80 #define MSGDSTRLEN 256 From 804cd1489e7802945aaa48e7eeb25ce04e9b9d32 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Wed, 6 Apr 2022 11:13:28 +0200 Subject: [PATCH 20/25] backport: Remove spurious include that keeps hypermail from compiling under macos --- src/file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/file.c b/src/file.c index cdfa67fe..5aafc834 100644 --- a/src/file.c +++ b/src/file.c @@ -53,9 +53,6 @@ #endif #endif /* HAVE_LIBFNV */ -extern int snprintf(char *str, size_t size, const char *format, ...); - - /* ** Does a file exist? */ From e5d42fbc476e97047d184414ae3fdb4f1dbf57a6 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Wed, 6 Apr 2022 11:32:49 +0200 Subject: [PATCH 21/25] 18n_replace_non_ascii_chars() was being called in parse.c even if ICONV_H was not true closes #86 --- src/parse.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/parse.c b/src/parse.c index 64f6c375..f5524a87 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1087,9 +1087,11 @@ static char *mdecodeRFC2047(char *string, int length, char *charsetsave) } else { free(storage); +#ifdef HAVE_ICONV /* make sure there are only ascii chars in the string ** for messages that don't respect rfc2047 */ i18n_replace_non_ascii_chars(string); +#endif return string; } } From b1b8a5ee55e9c70f4a28459be9a98dd3da3c392d Mon Sep 17 00:00:00 2001 From: jkbzh Date: Mon, 11 Apr 2022 11:33:52 +0200 Subject: [PATCH 22/25] Closes #84 Some C linkers require libraries to be declared after functions in that library are called, and not before. This was notably with -lm and -ltrio, where -lm had to be declared after -ltrio. --- Changelog | 7 +++++++ src/Makefile.in | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index c3ab1ad3..e77c5982 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,13 @@ Version Changes for Hypermail HYPERMAIL VERSION 2.4.1: ============================ +2022-11-04 Jose Kahan + * src/Makefile.in + Some C linkers require libraries to be declared after functions in that library + are called, and not before. This was notably with -lm and -ltrio, where -lm had + to be declared after -ltrio. + (closes # 84) + 2021-06-04 Baptiste Daroussin * src/uudecode.c src/parse.c Fixes for memory issues detected by libasan diff --git a/src/Makefile.in b/src/Makefile.in index 7f54bad0..2838fa4b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -40,7 +40,7 @@ CPPFLAGS=@CPPFLAGS@ @INCLUDES@ YACC=@YACC@ NETLIBS=@LIBS@ LDFLAGS=@LDFLAGS@ -MISC_LIBS= -lm -lpcre -ltrio +MISC_LIBS= -lpcre -ltrio -lm OPT_LIBS=@EXTRA_LIBS@ INCS= domains.h hypermail.h lang.h proto.h \ From 5ae032d1587c122663b048499d9ac021280f4880 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Mon, 11 Apr 2022 16:44:05 +0200 Subject: [PATCH 23/25] filter_non_ascii_chars() also needs to preserve htab chars --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 91b8812b..78ca1336 100644 --- a/src/string.c +++ b/src/string.c @@ -462,7 +462,7 @@ int i18n_replace_non_ascii_chars(char *string) while (*ptr) { if (!isascii(*ptr) || - (*ptr < 0x20 && *ptr != 0x0a && *ptr != 0x0d)) { + (*ptr < 0x20 && *ptr != 0x0a && *ptr != 0x0d && *ptr != 0x09)) { *ptr = '?'; count++; } From f941bec3c97192cb67a969b71ab452f0ee2b7e59 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Mon, 11 Apr 2022 17:08:10 +0200 Subject: [PATCH 24/25] reformatting --- Changelog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index e77c5982..b0411670 100644 --- a/Changelog +++ b/Changelog @@ -7,9 +7,9 @@ HYPERMAIL VERSION 2.4.1: 2022-11-04 Jose Kahan * src/Makefile.in - Some C linkers require libraries to be declared after functions in that library - are called, and not before. This was notably with -lm and -ltrio, where -lm had - to be declared after -ltrio. + Some C linkers require libraries to be declared after functions in that + library are called, and not before. This was notably with -lm and + -ltrio, where -lm had to be declared after -ltrio. (closes # 84) 2021-06-04 Baptiste Daroussin From 10c9cbe6e60e77e16e21b870e6c78eb1050f0438 Mon Sep 17 00:00:00 2001 From: jkbzh Date: Mon, 11 Apr 2022 17:50:16 +0200 Subject: [PATCH 25/25] Some refactoring and adding Changelog entry to PR #73 --- Changelog | 6 ++++++ docs/hmrc.html | 6 +++++- src/parse.c | 10 +++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Changelog b/Changelog index b0411670..25fb4c22 100644 --- a/Changelog +++ b/Changelog @@ -12,6 +12,12 @@ HYPERMAIL VERSION 2.4.1: -ltrio, where -lm had to be declared after -ltrio. (closes # 84) +2021-11-17 David Hughes + * docs/hmrc.html src/parse.c + Added support for strftime (3) formatting in the append_filename configuration + option to allow for archived messages to be split over multiple directories + (monthly or yearly for example) + 2021-06-04 Baptiste Daroussin * src/uudecode.c src/parse.c Fixes for memory issues detected by libasan diff --git a/docs/hmrc.html b/docs/hmrc.html index d2c97e74..4953123b 100644 --- a/docs/hmrc.html +++ b/docs/hmrc.html @@ -1301,7 +1301,11 @@

System miscellaneous

append = 1
append_filename = [ string ]
-
Specifies the filename to be used by the append option. $DIR may be used to specify a name relative to the directory specified in the -d or dir option. The string will be passed to strftime(3) to allow splitting the mailbox into yearly or monthy files, such as "%Y-%m.mbox".
+
Specifies the filename to be used by the append option. $DIR may +be used to specify a name relative to the directory specified in the +-d or dir option. The string will be passed to strftime(3) to allow +splitting the mailbox into yearly or monthy files, such as +"%Y-%m.mbox".

append_filename = $DIR/INBOX
diff --git a/src/parse.c b/src/parse.c index 91d5d2bb..aad1740e 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1536,7 +1536,6 @@ int parsemail(char *mbox, /* file name */ int num, isinheader, hassubject, hasdate; int num_added = 0; long exp_time = -1; - time_t curtime; time_t delete_older_than = (set_delete_older ? convtoyearsecs(set_delete_older) : 0); time_t delete_newer_than = (set_delete_newer ? convtoyearsecs(set_delete_newer) : 0); annotation_robot_t annotation_robot = ANNOTATION_ROBOT_NONE; @@ -1667,14 +1666,19 @@ int parsemail(char *mbox, /* file name */ *filename = 0; *pathname = 0; if (set_append_filename) { + time_t curtime; + const struct tm *local_curtime; + time(&curtime); + local_curtime = localtime(&curtime); + if(strncmp(set_append_filename, "$DIR/", 5) == 0) { strncpy(directory, dir, MAXFILELEN - 1); strftime(filename, MAXFILELEN - 1, set_append_filename+5, - localtime(&curtime)); + local_curtime); } else { strftime(filename, MAXFILELEN - 1, set_append_filename, - localtime(&curtime)); + local_curtime); } } else { strncpy(directory, dir, MAXFILELEN - 1);