]> git.ipfire.org Git - thirdparty/mlmmj.git/log
thirdparty/mlmmj.git
12 days agosb: update to latest version master
Baptiste Daroussin [Fri, 10 Jul 2026 18:17:35 +0000 (20:17 +0200)] 
sb: update to latest version

adapt to api changes (avoid collision with another lib)

13 days agorefactor: replace xstring by simpler sb_t
Baptiste Daroussin [Thu, 9 Jul 2026 06:30:46 +0000 (08:30 +0200)] 
refactor: replace xstring by simpler sb_t

2 weeks agovec: update to latest version
Baptiste Daroussin [Wed, 8 Jul 2026 08:21:42 +0000 (10:21 +0200)] 
vec: update to latest version

3 weeks agomaintd: factor bounce-entry skip prelude
Baptiste Daroussin [Sun, 28 Jun 2026 06:09:26 +0000 (08:09 +0200)] 
maintd: factor bounce-entry skip prelude

Extract bounce_skip() shared by probe_bouncers() and unsub_bouncers():
the identical skip-".","..","-probe",".lastmsg", stat-check, and
probe-already-out prelude.  Centralizes the "what is an active bounce
entry" rule.  Behavior unchanged; covered by the mlmmj-maintd
functional tests.

3 weeks agoarchive_migrate: use strlist instead of manual realloc
Baptiste Daroussin [Sun, 28 Jun 2026 06:02:30 +0000 (08:02 +0200)] 
archive_migrate: use strlist instead of manual realloc

Replace the hand-rolled char **names / nnames / namesalloc doubling
array with a strlist (vec_t(char *)), using vec_push to collect,
vec_free_and_free on the early-return path, and vec_free after the
per-element frees in the migration loop.  Covered by the existing
archive_migrate tests.

3 weeks agoAdd send_or_queue, factor send-or-refile
Baptiste Daroussin [Sun, 28 Jun 2026 05:57:51 +0000 (07:57 +0200)] 
Add send_or_queue, factor send-or-refile

Extract the send_single_mail + save_queue/unlink + fclose block
into send_or_queue() in send_mail.c and use it in send_help and
subscriberfuncs where it was duplicated verbatim.  Add a unit test
covering both the success (queue file removed) and smtp-failure
(refiled, file kept) paths.

3 weeks agoAdd mkuniqfileat, factor unique-file creation
Baptiste Daroussin [Sun, 28 Jun 2026 05:51:37 +0000 (07:51 +0200)] 
Add mkuniqfileat, factor unique-file creation

Centralize the random_str + O_CREAT|O_EXCL + EEXIST retry recipe into
mkuniqfileat() and use it in mlmmj-receive, subscriberfuncs (subconf),
send_digest and prepstdreply.  Two sites reusing the random suffix as
a cookie are left unchanged.  Add a unit test.

3 weeks agoFactor subscriber search, fix prefix/CRLF bugs
Baptiste Daroussin [Sat, 27 Jun 2026 08:35:50 +0000 (10:35 +0200)] 
Factor subscriber search, fix prefix/CRLF bugs

Extract find_addr_line() in subscriberfuncs.c: a shared, mmap-based
case-insensitive line search used by both find_subscriber() and
unsubscribe().  It requires an exact-length, full-line match and
tolerates a trailing CR, replacing two divergent implementations.

find_subscriber() moves from getline+chomp+strcasecmp to mmap +
find_addr_line(), matching the zero-copy style already used by
unsubscribe().

unsubscribe() drops its open-coded search, which had two latent
bugs now fixed by the shared helper: an empty line matched any
address (strncasecmp n=0) and a prefix line matched a longer
address (strncasecmp without length equality), the latter causing
posend to overrun and corrupt the file on splice.  posend now also
skips a trailing CR before newlines so CRLF files splice cleanly.

Add unit tests locking the contract: find_addr_line edge cases
(exact/CRLF/no-newline hits, prefix and empty-line non-matches),
is_subbed across a non-shard file with CRLF and prefix lines, and
unsubscribe preserving a prefix line and bystander around a CRLF
target.

3 weeks agoRewrite parse_content_type with strview
Baptiste Daroussin [Fri, 26 Jun 2026 15:39:54 +0000 (17:39 +0200)] 
Rewrite parse_content_type with strview

Introduce include/strview.h and replace the manual char-by-char
parsing of Content-Type in mlmmj.c with zero-copy strview views and
a small sv_span_until helper for the "stop at any of these chars"
rule. Quoted/bare media types and quoted/bare boundary handling
keep identical semantics.

Extend the parse_content_type unit test to lock the contract before
and after the change: quoted boundaries (with embedded whitespace),
space-terminated types, case-insensitive boundary=, parameters
before the boundary, quoted and unclosed-quoted media types.

3 weeks agoSync xmalloc/xstring helpers, migrate decode_qp
Baptiste Daroussin [Fri, 26 Jun 2026 15:35:33 +0000 (17:35 +0200)] 
Sync xmalloc/xstring helpers, migrate decode_qp

Add configurable XALLOC_ERROR to xmalloc.h (default still abort())
and extend xstring.h with printf/puts/putc/write macros,
xstring_renew, xstring_get_binary, and a NULL guard in
xstring_get. All existing call sites keep working.

Rewrite decode_qp() in strgen.c to use the xstring builder
instead of a raw open_memstream buffer, dropping manual
buffer/size handling.

5 weeks agoRelease: 2.1.0 RELEASE_2_1_0
Baptiste Daroussin [Fri, 12 Jun 2026 15:25:13 +0000 (17:25 +0200)] 
Release: 2.1.0

5 weeks agomlmmj-sub: add batch subscribe via stdin
Baptiste Daroussin [Fri, 12 Jun 2026 14:56:56 +0000 (16:56 +0200)] 
mlmmj-sub: add batch subscribe via stdin

Support -a - to read addresses from stdin (one per line).
Lines starting with # or empty are ignored.
Invalid addresses (no @) are skipped with a warning.

closes: #90

5 weeks agofixed a typo (wasn't escaping quotation marks).
Martin Preuss [Sat, 16 May 2026 14:53:44 +0000 (16:53 +0200)] 
fixed a typo (wasn't escaping quotation marks).

5 weeks agoAdd $disarmedfrom$ substitution in customheaders
Baptiste Daroussin [Fri, 12 Jun 2026 13:09:07 +0000 (15:09 +0200)] 
Add $disarmedfrom$ substitution in customheaders

Expands to the disarmed From: header value ("<" -> "(", ">" -> ")",
"@" -> "=").  Complements the existing $posteraddr$ variable.

5 weeks agoREADME: document $posteraddr$ and DKIM/From munging recipe
Baptiste Daroussin [Fri, 12 Jun 2026 13:01:46 +0000 (15:01 +0200)] 
README: document $posteraddr$ and DKIM/From munging recipe

Explain the $posteraddr$ variable available in control/customheaders
and provide a complete recipe for DKIM-friendly From: rewriting using
only existing control files (customheaders, delheaders, replyto).
This makes PR #102 (From munging via control/munge) unnecessary.

5 weeks agomlmmj: remove duplicate includes
Baptiste Daroussin [Fri, 12 Jun 2026 11:45:04 +0000 (13:45 +0200)] 
mlmmj: remove duplicate includes

Remove duplicate #include lines in mlmmj-send.c (extra <signal.h>),
mlmmj-bounce.c (extra <string.h>), and
contrib/receivestrip/mlmmj-receive-strip.c (extra <string.h> and
"utils.h").

5 weeks agomlmmj: constify static string tables
Baptiste Daroussin [Fri, 12 Jun 2026 11:42:33 +0000 (13:42 +0200)] 
mlmmj: constify static string tables

Declare action_strs, modreason_strs, subtype_strs, subreason_strs,
and subtypes arrays as const char * const to put them in .rodata
and allow the compiler to optimize better.

5 weeks agomlmmj-send: use <stdbool.h> instead of "stdbool.h"
Baptiste Daroussin [Fri, 12 Jun 2026 11:40:03 +0000 (13:40 +0200)] 
mlmmj-send: use <stdbool.h> instead of "stdbool.h"

The project has no local stdbool.h; use the standard system header
inclusion form.

5 weeks agomlmmj: remove obsolete RCS/CVS $Id$ tags
Baptiste Daroussin [Fri, 12 Jun 2026 11:37:52 +0000 (13:37 +0200)] 
mlmmj: remove obsolete RCS/CVS $Id$ tags

Remove 14 $Id$ lines from source files. These tags are remnants of
the CVS era and serve no purpose under git version control.

5 weeks agomlmmj: remove dead code (#if 0 blocks)
Baptiste Daroussin [Fri, 12 Jun 2026 11:37:46 +0000 (13:37 +0200)] 
mlmmj: remove dead code (#if 0 blocks)

Remove 6 #if 0 blocks across 5 source files that contained dead code
(commented-out log_error/printf statements).

5 weeks agomlmmj: change valuecount from int to size_t
Baptiste Daroussin [Fri, 12 Jun 2026 09:35:44 +0000 (11:35 +0200)] 
mlmmj: change valuecount from int to size_t

The valuecount field in struct mailhdr was int but is used as a loop
counter and array index. Change it to size_t and update the loops
in free_mailhdrs() and mlmmj-process.c to use size_t consistently,
eliminating signed/unsigned comparison warnings.

5 weeks agomlmmj-send: fix gotsigterm to be volatile sig_atomic_t
Baptiste Daroussin [Fri, 12 Jun 2026 09:31:23 +0000 (11:31 +0200)] 
mlmmj-send: fix gotsigterm to be volatile sig_atomic_t

Per POSIX, variables shared between signal handlers and the main
execution context must be volatile sig_atomic_t, otherwise their
read/write is not guaranteed to be atomic in a signal context.

5 weeks agomlmmj-receive: remove dead code (#if 0 block)
Baptiste Daroussin [Fri, 12 Jun 2026 09:27:54 +0000 (11:27 +0200)] 
mlmmj-receive: remove dead code (#if 0 block)

The #if 0 block containing log_oper() was dead code. Remove it.

5 weeks agoSimplify send_digest: remove goto fallback_subject
Baptiste Daroussin [Mon, 8 Jun 2026 21:54:02 +0000 (23:54 +0200)] 
Simplify send_digest: remove goto fallback_subject

Replace the goto-based fallback pattern with a natural if/else flow.
The subject is now parsed inside an if (txt != NULL) block, and the
fallback is generated when subject remains NULL. This also fixes a
memory leak: when "too many headers" occurred, the old code jumped
to fallback_subject without freeing the last get_processed_text_line
allocation.

5 weeks agoSimplify bouncemail: merge duplicate confsub/confunsub paths
Baptiste Daroussin [Mon, 8 Jun 2026 21:36:06 +0000 (23:36 +0200)] 
Simplify bouncemail: merge duplicate confsub/confunsub paths

The confsub and confunsub blocks were identical except for the directory
name ('subconf' vs 'unsubconf'). Merge them into a single block that
derives the directory name from the identifier string.

5 weeks agoSimplify do_access action parsing with lookup table
Baptiste Daroussin [Mon, 8 Jun 2026 21:35:48 +0000 (23:35 +0200)] 
Simplify do_access action parsing with lookup table

Replace the if/else chain for action keyword matching with a struct-based
lookup table and a parse_action() helper. This makes adding new actions
easier (just add to action_keywords[]) and eliminates the ACT_DENY
sentinel-overload issue.

5 weeks agoSimplify initsmtp: replace do/while(1) with for(;;) and direct returns
Baptiste Daroussin [Mon, 8 Jun 2026 21:35:27 +0000 (23:35 +0200)] 
Simplify initsmtp: replace do/while(1) with for(;;) and direct returns

The old code used a do/while(1) loop with scattered break/continue and
a retval variable set before each break. The new code returns each error
code directly where the decision is made, making the EHLO→HELO fallback
flow much easier to follow.

Also fix: the old code had a misleading comment 'EHLO successful don't
try more' on the HELO break path.

5 weeks agoFix send_help_noexit, send_mail_from_file, generate_subconfirm: check fopen return
Baptiste Daroussin [Mon, 8 Jun 2026 21:18:59 +0000 (23:18 +0200)] 
Fix send_help_noexit, send_mail_from_file, generate_subconfirm: check fopen return

If fopen() on the queue file fails, send_mail() treats NULL fp as "no
mail to send" and returns 0 (success). send_single_mail() then returns
true, causing the queue file to be unlink()ed without ever being
delivered — silent data loss.

Add explicit fopen return checks in all functions that previously
omitted them.

5 weeks agoFix do_access: add missing NULL check on msg parameter
Baptiste Daroussin [Mon, 8 Jun 2026 21:18:44 +0000 (23:18 +0200)] 
Fix do_access: add missing NULL check on msg parameter

The final fallthrough path (no rules matched) called xasprintf(msg, ...)
without checking if msg != NULL, unlike all other xasprintf calls in the
same function. If a caller passes NULL for msg, this would crash in
vasprintf(NULL, ...).

5 weeks agoFix send_probe: detect fopen failure and return false early
Baptiste Daroussin [Mon, 8 Jun 2026 21:04:50 +0000 (23:04 +0200)] 
Fix send_probe: detect fopen failure and return false early

If fopen(queuefilename, "r") fails, mail.fp stays NULL. send_mail()
treats NULL fp as "no mail to send" and returns success, causing
send_probe() to silently report success without sending anything.
Now we check for NULL fp immediately and return failure.

5 weeks agoFix fdopendir UB: use dirfd() instead of raw fd after fdopendir
Baptiste Daroussin [Mon, 8 Jun 2026 21:03:03 +0000 (23:03 +0200)] 
Fix fdopendir UB: use dirfd() instead of raw fd after fdopendir

POSIX states that after fdopendir(), the file descriptor is under the
control of the system and must not be used directly. Use dirfd() to
retrieve the fd from the DIR stream for subsequent openat() calls.

Rename parameter in is_subbed_in() from "dirfd" to "subddir_fd" to
avoid naming collision with the POSIX dirfd() function.

6 weeks agoFix textcontent: return early when openat fails instead of calling close(-1)
Baptiste Daroussin [Mon, 8 Jun 2026 20:48:45 +0000 (22:48 +0200)] 
Fix textcontent: return early when openat fails instead of calling close(-1)

When openat() for the "text" subdirectory fails, fd is -1. The old code
passed fd=-1 to ctrlval() which would return NULL, but then closed(-1)
which is a no-op that sets errno=EBADF unnecessarily.

6 weeks agoFix process_headers: stop at blank line instead of skipping it
Baptiste Daroussin [Mon, 8 Jun 2026 20:48:12 +0000 (22:48 +0200)] 
Fix process_headers: stop at blank line instead of skipping it

process_headers() used "continue" for empty/whitespace-only lines,
causing it to keep reading past the end-of-headers marker into body
content. Changed to "break" so it properly terminates at the blank
line as per RFC 5322.

Add test to verify body content after blank line is not processed.

6 weeks agoFix write_mailbody: eliminate double ungetc and EOF pushback in dot-stuffing
Baptiste Daroussin [Mon, 8 Jun 2026 20:47:20 +0000 (22:47 +0200)] 
Fix write_mailbody: eliminate double ungetc and EOF pushback in dot-stuffing

The old code called ungetc() twice without an intervening read in the
dot-stuffing path (C standard guarantees only one ungetc between reads),
and also passed EOF to ungetc() when the dot was the last character in
the file (undefined behavior).

Fix by outputting the original dot character directly via fputc() after
dot-stuffing instead of pushing it back via ungetc(), and only calling
ungetc() when the character is not EOF.

6 weeks agoFix random_int: validate readn() return to prevent using uninitialized data
Baptiste Daroussin [Mon, 8 Jun 2026 20:46:21 +0000 (22:46 +0200)] 
Fix random_int: validate readn() return to prevent using uninitialized data

If readn() fails (returns -1) or reads fewer than 4 bytes, val would
have been returned with uninitialized stack data. Now we initialize val
to 0 and only use it when readn() reports exactly 4 bytes read.

Also remove dead code (#if 0 test main).

6 weeks agoFix chomp: remove buggy early-return corrupting multi-newline strings
Baptiste Daroussin [Mon, 8 Jun 2026 20:45:29 +0000 (22:45 +0200)] 
Fix chomp: remove buggy early-return corrupting multi-newline strings

The old code returned immediately when a string started with \n or \r,
only stripping the first character. For inputs like "\n\n" or "\r\n\r\n"
this left trailing newlines intact.

Rewrite to strip trailing newlines from the end of the string,
which correctly handles all cases including multi-newline strings.

Add test cases for the previously broken inputs.

6 weeks agomlmmj-send: replace vec_pop_front with index-based iteration
Baptiste Daroussin [Mon, 8 Jun 2026 20:34:59 +0000 (22:34 +0200)] 
mlmmj-send: replace vec_pop_front with index-based iteration

In send_mail_many_list(), vec_pop_front() is O(n) because it shifts
every remaining element on each pop.  Replace it with a simple index
that walks the strlist array in place, giving O(1) per element.

On failure (SIGTERM or send error), a temporary strlist pointing to
the remaining entries is passed to requeuemail().  The remaining
entries are freed after requeuemail() has written them to disk.

6 weeks agoFix: update text_0/text_1 tests for Date header instead of duplicate Message-Id
Baptiste Daroussin [Mon, 8 Jun 2026 19:52:58 +0000 (21:52 +0200)] 
Fix: update text_0/text_1 tests for Date header instead of duplicate Message-Id

The tests expected two Message-Id headers, matching the old copy-paste bug
in prepstdreply_to(). Now expect the correct Date header via gendatestr().

6 weeks agoTest: verify only one Reply-To header with multiple From
Baptiste Daroussin [Mon, 8 Jun 2026 19:39:46 +0000 (21:39 +0200)] 
Test: verify only one Reply-To header with multiple From

Add test voodoo_replyto_once to verify that when the input
has multiple From: headers, only one Reply-To header is
generated (regression test for the previous fix).

6 weeks agoFix: mmap/fd leak in unsubscribe()
Baptiste Daroussin [Mon, 8 Jun 2026 19:34:11 +0000 (21:34 +0200)] 
Fix: mmap/fd leak in unsubscribe()

When a subscriber file only contains the address to unsubscribe,
the file is deleted but the mmap and file descriptor are not
unmapped/closed before continue, leaking resources.

6 weeks agoFix: write only one Reply-To header
Baptiste Daroussin [Mon, 8 Jun 2026 19:32:22 +0000 (21:32 +0200)] 
Fix: write only one Reply-To header

When replyto is set, a Reply-To header was written for every
From: header in the email. Track whether we already wrote one
to avoid duplicates.

6 weeks agoFix: memory leak in prepstdreply_to() and copy-paste bug
Baptiste Daroussin [Mon, 8 Jun 2026 19:31:24 +0000 (21:31 +0200)] 
Fix: memory leak in prepstdreply_to() and copy-paste bug

Free headers[] on all error paths in prepstdreply_to().
Also fix headers[3] which was set to msgid instead of gendatestr()
when a msgid parameter was provided.

6 weeks agoFix: detect hostname truncation in hostnamestr()
Baptiste Daroussin [Mon, 8 Jun 2026 19:21:15 +0000 (21:21 +0200)] 
Fix: detect hostname truncation in hostnamestr()

gethostname() can return 0 with a truncated hostname. Check
strlen() instead of relying on the pre-set null terminator.

6 weeks agoFix: check newlocale() return value in gendatestr()
Baptiste Daroussin [Mon, 8 Jun 2026 19:19:34 +0000 (21:19 +0200)] 
Fix: check newlocale() return value in gendatestr()

newlocale() can return (locale_t)0 on failure. Passing a null locale
to strftime_l() is undefined behavior. Fall back to strftime().

7 weeks agoUpdate README.sendmail.md
falken [Sun, 31 May 2026 16:10:07 +0000 (18:10 +0200)] 
Update README.sendmail.md

7 weeks agoUpdate README.sendmail.md
falken [Sun, 31 May 2026 16:06:55 +0000 (18:06 +0200)] 
Update README.sendmail.md

7 weeks agoUpdate README.sendmail.md
falken [Sun, 31 May 2026 15:43:23 +0000 (17:43 +0200)] 
Update README.sendmail.md

7 weeks agoAdd initial set up notes
falken [Sun, 31 May 2026 15:41:33 +0000 (17:41 +0200)] 
Add initial set up notes

7 weeks agoci: kyua is in freebsd base now
Baptiste Daroussin [Tue, 2 Jun 2026 13:45:13 +0000 (15:45 +0200)] 
ci: kyua is in freebsd base now

7 weeks agoSync with latest bbuild
Baptiste Daroussin [Sun, 31 May 2026 08:33:00 +0000 (10:33 +0200)] 
Sync with latest bbuild

- Replace configure with latest bbuild version (adds write_if_changed,
  HAVE_DECL_* handling, --includedir, --libdir, pkgconfigdir default)
- Update mk/defs.mk.in with PACKAGE_NAME and VERSION
- Update mk/prog.mk and mk/common.mk to latest bbuild

2 months agomake: fixes to clean target 101/head
Uffe Jakobsen [Mon, 18 May 2026 09:32:02 +0000 (11:32 +0200)] 
make: fixes to clean target

2 months agoFix compile warnings 100/head
Uffe Jakobsen [Sun, 17 May 2026 22:24:45 +0000 (00:24 +0200)] 
Fix compile warnings

ArchLinux: gcc version 16.1.1 20260430 (GCC)

mlmmj.c: In function ‘bouncemail’:
mlmmj.c:450:21: warning: unused variable ‘st’ [-Wunused-variable]
  450 |         struct stat st;
      |                     ^~

In file included from mlmmj.c:23:
mlmmj.c: In function ‘atfu_find_in_list_body’:
/tmp/mlmmj-devel.git/include/vec.h:93:15: warning: value computed is not used [-Wunused-value]
   93 |         (v)->d[--(v)->len]
      |         ~~~~~~^~~~~~~~~~~~
mlmmj.c:3611:9: note: in expansion of macro ‘vec_pop’
 3611 |         vec_pop(&bla);
      |         ^~~~~~~

ArchLinux: clang version 22.1.5

mlmmj-process.c:829:19: warning: variable 'txt' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
  829 |                             } else if (modonlypost) {
      |                                        ^~~~~~~~~~~
mlmmj-process.c:833:18: note: uninitialized use occurs here
  833 |                             MY_ASSERT(txt);
      |                                       ^~~
mlmmj-process.c:829:15: note: remove the 'if' if its condition is always true
  829 |                             } else if (modonlypost) {
      |                                    ^~~~~~~~~~~~~~~~
mlmmj-process.c:287:11: note: initialize the variable 'txt' to silence this warning
  287 |         text *txt;
      |                  ^
      |                   = NULL

2 months agoAdd editorconfig to project
Uffe Jakobsen [Fri, 15 May 2026 19:09:35 +0000 (21:09 +0200)] 
Add editorconfig to project

2 months agofix: tests: clean up cannot remove dir 97/head
Uffe Jakobsen [Fri, 15 May 2026 21:30:01 +0000 (23:30 +0200)] 
fix: tests: clean up cannot remove dir

2 months agofakesmtpd: do not leave zombies
Baptiste Daroussin [Sun, 10 May 2026 12:53:03 +0000 (14:53 +0200)] 
fakesmtpd: do not leave zombies

fixes: #95

2 months agoAdd MIME type detection/rejection to mlmmj-receive
Baptiste Daroussin [Sat, 9 May 2026 12:09:25 +0000 (14:09 +0200)] 
Add MIME type detection/rejection to mlmmj-receive

When control/mimedeny exists, parse MIME headers and body to detect
unwanted MIME types in both top-level and multipart sub-parts.  Adds
an X-ThisMailContainsUnwantedMimeParts header (Y/N) without stripping
any content.

New functions: read_headers(), write_headers(),
update_unwanted_mime_header(), parse_body(), process_mail().

If control/mimedeny is absent, behavior is unchanged (dumpfd2fd).

Fixes from contrib/receivestrip/:
- use-after-free in header reading (free after vec_push)
- boundary detection missing "--" prefix in MIME body

Tests: mimedeny_simple, mimedeny_none, mimedeny_nocontenttype,
mimedeny_multipart

2 months agofix: remove double semicolon in subscribe_type()
Baptiste Daroussin [Fri, 8 May 2026 06:38:12 +0000 (08:38 +0200)] 
fix: remove double semicolon in subscribe_type()

2 months agofix: remove trailing semicolon from gen_addr_cookie macro
Baptiste Daroussin [Fri, 8 May 2026 06:37:47 +0000 (08:37 +0200)] 
fix: remove trailing semicolon from gen_addr_cookie macro

2 months ago2.0.2 RELEASE_2_0_1
Baptiste Daroussin [Thu, 23 Apr 2026 11:55:04 +0000 (13:55 +0200)] 
2.0.2

2 months agofix toolchain override
Baptiste Daroussin [Thu, 23 Apr 2026 11:52:45 +0000 (13:52 +0200)] 
fix toolchain override

2 months agoRelease 2.0.1
Baptiste Daroussin [Thu, 23 Apr 2026 11:42:19 +0000 (13:42 +0200)] 
Release 2.0.1

2 months agoDo not install static only libraries
Baptiste Daroussin [Thu, 23 Apr 2026 11:41:47 +0000 (13:41 +0200)] 
Do not install static only libraries

2 months agofix configugre with --mandir option
Baptiste Daroussin [Thu, 23 Apr 2026 11:39:05 +0000 (13:39 +0200)] 
fix configugre with --mandir option

2 months agobuild: fix warnings RELEASE_2_0_0
Baptiste Daroussin [Thu, 23 Apr 2026 08:41:28 +0000 (10:41 +0200)] 
build: fix warnings

2 months agoFix CI after removal of autotools
Baptiste Daroussin [Thu, 23 Apr 2026 07:46:34 +0000 (09:46 +0200)] 
Fix CI after removal of autotools

2 months agoRelease 2.0.0
Baptiste Daroussin [Thu, 23 Apr 2026 07:40:57 +0000 (09:40 +0200)] 
Release 2.0.0

2 months agobuild: bbuild system
Baptiste Daroussin [Thu, 23 Apr 2026 07:16:40 +0000 (09:16 +0200)] 
build: bbuild system

3 months agoAdd the ability to run make distcheck
Baptiste Daroussin [Wed, 22 Apr 2026 11:27:14 +0000 (13:27 +0200)] 
Add the ability to run make distcheck

3 months agofix tests
Baptiste Daroussin [Wed, 22 Apr 2026 11:02:58 +0000 (13:02 +0200)] 
fix tests

3 months agoTUNABLES: clarify the documentation for subonlypost and modonlypost
Baptiste Daroussin [Fri, 17 Apr 2026 09:33:09 +0000 (11:33 +0200)] 
TUNABLES: clarify the documentation for subonlypost and modonlypost

Fixes: #93
3 months agosubrelease: if there are moderator defined, then deactivate subrelease
Baptiste Daroussin [Fri, 17 Apr 2026 07:44:52 +0000 (09:44 +0200)] 
subrelease: if there are moderator defined, then deactivate subrelease

3 months agomove the installation back to bin
Baptiste Daroussin [Tue, 7 Apr 2026 20:03:46 +0000 (22:03 +0200)] 
move the installation back to bin

3 months agoresend_queue: do not leak a fd
Baptiste Daroussin [Mon, 30 Mar 2026 20:23:44 +0000 (22:23 +0200)] 
resend_queue: do not leak a fd

Instead reset temporarily the CLOEXEC flag and reset it later

3 months agoresend_queue: pass the archive directory via fd to mlmmj-send
Baptiste Daroussin [Mon, 30 Mar 2026 17:47:09 +0000 (19:47 +0200)] 
resend_queue: pass the archive directory via fd to mlmmj-send

duplicate the filedescriptor which archive_open explicitly mark as
O_CLOEXEC.

3 months agoarchive_open: remove ctrlfd argument
Baptiste Daroussin [Mon, 30 Mar 2026 17:42:35 +0000 (19:42 +0200)] 
archive_open: remove ctrlfd argument

It was intended to be used in the future but I change my mind on its
usage

3 months agoarchive_migrate: stop polluting the logs
Baptiste Daroussin [Mon, 30 Mar 2026 17:38:37 +0000 (19:38 +0200)] 
archive_migrate: stop polluting the logs

3 months agoPrepare release 2.0.0
Baptiste Daroussin [Sun, 29 Mar 2026 08:07:42 +0000 (10:07 +0200)] 
Prepare release 2.0.0

3 months agodocumentation: update with latest features
Baptiste Daroussin [Sun, 29 Mar 2026 08:01:58 +0000 (10:01 +0200)] 
documentation: update with latest features

3 months agoadd optional YYYY/MM archive partitioning via control/archivepartition
Baptiste Daroussin [Sun, 29 Mar 2026 06:21:04 +0000 (08:21 +0200)] 
add optional YYYY/MM archive partitioning via control/archivepartition

Large mailing lists accumulate thousands of files in a single archive/
directory, degrading filesystem performance. When control/archivepartition
exists, new archives are written to archive/YYYY/MM/N and mlmmj-maintd
automatically migrates existing flat archives based on file mtime.
Reading always tries flat layout first then falls back to scanning
subdirectories, so archives work regardless of layout.

3 months agogenerate RFC 2919/2369 List-* and Precedence headers natively
Baptiste Daroussin [Sun, 29 Mar 2026 05:55:55 +0000 (07:55 +0200)] 
generate RFC 2919/2369 List-* and Precedence headers natively

Mailing list messages without List-Id/Precedence headers cause vacation
autoreplies to trigger bounces leading to unsubscriptions, prevent mail
clients like Delta Chat from detecting list messages, and hurt
deliverability with major providers.

Generate List-Id, List-Post, List-Help, List-Subscribe, List-Unsubscribe,
and Precedence headers by default in do_all_the_voodoo_here(). List-Owner
is included only when control/owner exists. All headers can be disabled
via control/nolistheaders.

3 months agomlmmj-make-ml: use full email address for default owner
Baptiste Daroussin [Sun, 29 Mar 2026 02:52:18 +0000 (04:52 +0200)] 
mlmmj-make-ml: use full email address for default owner

The default owner "postmaster" lacks a domain part, causing
mlmmj-send to reject it with "No @ in address". Use the FQDN
already collected earlier in the script to build a proper
postmaster@FQDN default.

Closes #36

3 months agosend_mail: add X-Forwarded-To and X-Signed-Recipient headers
Baptiste Daroussin [Sun, 29 Mar 2026 02:38:25 +0000 (04:38 +0200)] 
send_mail: add X-Forwarded-To and X-Signed-Recipient headers

Add per-recipient headers to improve deliverability and support DARA
(draft ARC replay-resistant authentication):

- X-Forwarded-To: helps Gmail recognize legitimate forwarding
- X-Signed-Recipient: used in ARC signatures to prove the message
  was intended for a specific recipient

Both are enabled independently via control files (xforwardedto and dara).
Like addtohdr, these are incompatible with VERP since they require
per-recipient header injection.

Closes #34

3 months agosubscription: follow reply-to on susbcription
Baptiste Daroussin [Sat, 28 Mar 2026 21:55:02 +0000 (22:55 +0100)] 
subscription: follow reply-to on susbcription

3 months agotreat exit 127 ass error
Baptiste Daroussin [Sat, 28 Mar 2026 20:46:55 +0000 (21:46 +0100)] 
treat exit 127 ass error

posix_spawnp(3) may report exec() failures via the
child's exit status (127) instead of the return value

3 months agosyslog: only support system with syslog
Baptiste Daroussin [Fri, 27 Mar 2026 20:31:41 +0000 (21:31 +0100)] 
syslog: only support system with syslog

3 months agofix build
Baptiste Daroussin [Fri, 27 Mar 2026 20:15:01 +0000 (21:15 +0100)] 
fix build

3 months agoadd forgotten configure scrip
Baptiste Daroussin [Fri, 27 Mar 2026 20:11:31 +0000 (21:11 +0100)] 
add forgotten configure scrip

3 months agobuild system, convert to autosetup + custom mk framework
Baptiste Daroussin [Fri, 27 Mar 2026 12:54:19 +0000 (13:54 +0100)] 
build system, convert to autosetup + custom mk framework

3 months agoReplace foot's tllist.h with my own vec.h
Baptiste Daroussin [Fri, 27 Mar 2026 09:36:26 +0000 (10:36 +0100)] 
Replace foot's tllist.h with my own vec.h

I wrote for FreeBSD's pkg manager, no functionnal change expected

3 months agoplug memory leak
Baptiste Daroussin [Fri, 27 Mar 2026 07:44:47 +0000 (08:44 +0100)] 
plug memory leak

3 months agoUTF8: prevent out of bound reading
Baptiste Daroussin [Fri, 27 Mar 2026 07:40:26 +0000 (08:40 +0100)] 
UTF8: prevent out of bound reading

3 months agoplug memory leak and fix naming collision
Baptiste Daroussin [Fri, 27 Mar 2026 07:36:50 +0000 (08:36 +0100)] 
plug memory leak and fix naming collision

3 months agoFix fd leak
Baptiste Daroussin [Fri, 27 Mar 2026 07:17:11 +0000 (08:17 +0100)] 
Fix fd leak

3 months agofix TOCTOU by using O_NOFOLLOW which also simplifies code
Baptiste Daroussin [Fri, 27 Mar 2026 07:13:01 +0000 (08:13 +0100)] 
fix TOCTOU by using O_NOFOLLOW which also simplifies code

3 months agolimite line length to maximum 64k
Baptiste Daroussin [Fri, 27 Mar 2026 06:58:52 +0000 (07:58 +0100)] 
limite line length to maximum 64k

3 months agosetgid: test for failures
Baptiste Daroussin [Fri, 27 Mar 2026 06:51:25 +0000 (07:51 +0100)] 
setgid: test for failures

3 months agoadd forgotten setgid
Baptiste Daroussin [Fri, 27 Mar 2026 06:50:08 +0000 (07:50 +0100)] 
add forgotten setgid

3 months agoharden email validations
Baptiste Daroussin [Fri, 27 Mar 2026 06:34:13 +0000 (07:34 +0100)] 
harden email validations

3 months agomail: prevent header injections
Baptiste Daroussin [Fri, 27 Mar 2026 05:59:27 +0000 (06:59 +0100)] 
mail: prevent header injections

while theorically impossible as prefiltered by
MTA, I am aware of usages of mlmmj where inputs
are not through MTA, so better be safe than sorry

3 months agofix bad error message
Baptiste Daroussin [Fri, 27 Mar 2026 05:41:30 +0000 (06:41 +0100)] 
fix bad error message